mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	tracing: Add ref count to tracer for when they are being read by pipe
When one of the trace pipe files are being read (by either the trace_pipe or trace_pipe_raw), do not allow the current_trace to change. By adding a ref count that is incremented when the pipe files are opened, will prevent the current_trace from being changed. This will allow for the removal of the global trace_types_lock from reading the pipe buffers (which is currently a bottle neck). Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
This commit is contained in:
		
							parent
							
								
									97bf6af1f9
								
							
						
					
					
						commit
						cf6ab6d914
					
				
					 2 changed files with 16 additions and 1 deletions
				
			
		| 
						 | 
					@ -4140,6 +4140,12 @@ static int tracing_set_tracer(struct trace_array *tr, const char *buf)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* If trace pipe files are being read, we can't change the tracer */
 | 
				
			||||||
 | 
						if (tr->current_trace->ref) {
 | 
				
			||||||
 | 
							ret = -EBUSY;
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	trace_branch_disable();
 | 
						trace_branch_disable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tr->current_trace->enabled--;
 | 
						tr->current_trace->enabled--;
 | 
				
			||||||
| 
						 | 
					@ -4363,6 +4369,8 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp)
 | 
				
			||||||
		iter->trace->pipe_open(iter);
 | 
							iter->trace->pipe_open(iter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nonseekable_open(inode, filp);
 | 
						nonseekable_open(inode, filp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tr->current_trace->ref++;
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	mutex_unlock(&trace_types_lock);
 | 
						mutex_unlock(&trace_types_lock);
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
| 
						 | 
					@ -4382,6 +4390,8 @@ static int tracing_release_pipe(struct inode *inode, struct file *file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mutex_lock(&trace_types_lock);
 | 
						mutex_lock(&trace_types_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tr->current_trace->ref--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (iter->trace->pipe_close)
 | 
						if (iter->trace->pipe_close)
 | 
				
			||||||
		iter->trace->pipe_close(iter);
 | 
							iter->trace->pipe_close(iter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5331,6 +5341,8 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	filp->private_data = info;
 | 
						filp->private_data = info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tr->current_trace->ref++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mutex_unlock(&trace_types_lock);
 | 
						mutex_unlock(&trace_types_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = nonseekable_open(inode, filp);
 | 
						ret = nonseekable_open(inode, filp);
 | 
				
			||||||
| 
						 | 
					@ -5437,6 +5449,8 @@ static int tracing_buffers_release(struct inode *inode, struct file *file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mutex_lock(&trace_types_lock);
 | 
						mutex_lock(&trace_types_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						iter->tr->current_trace->ref--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	__trace_array_put(iter->tr);
 | 
						__trace_array_put(iter->tr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (info->spare)
 | 
						if (info->spare)
 | 
				
			||||||
| 
						 | 
					@ -6416,7 +6430,7 @@ static int instance_delete(const char *name)
 | 
				
			||||||
		goto out_unlock;
 | 
							goto out_unlock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = -EBUSY;
 | 
						ret = -EBUSY;
 | 
				
			||||||
	if (tr->ref)
 | 
						if (tr->ref || (tr->current_trace && tr->current_trace->ref))
 | 
				
			||||||
		goto out_unlock;
 | 
							goto out_unlock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	list_del(&tr->list);
 | 
						list_del(&tr->list);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -388,6 +388,7 @@ struct tracer {
 | 
				
			||||||
	struct tracer		*next;
 | 
						struct tracer		*next;
 | 
				
			||||||
	struct tracer_flags	*flags;
 | 
						struct tracer_flags	*flags;
 | 
				
			||||||
	int			enabled;
 | 
						int			enabled;
 | 
				
			||||||
 | 
						int			ref;
 | 
				
			||||||
	bool			print_max;
 | 
						bool			print_max;
 | 
				
			||||||
	bool			allow_instances;
 | 
						bool			allow_instances;
 | 
				
			||||||
#ifdef CONFIG_TRACER_MAX_TRACE
 | 
					#ifdef CONFIG_TRACER_MAX_TRACE
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue