diff options
Diffstat (limited to 'kernel/trace/trace.c')
| -rw-r--r-- | kernel/trace/trace.c | 173 | 
1 files changed, 79 insertions, 94 deletions
| diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 7896d30d90f7..f9139dc1262c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -512,12 +512,6 @@ int call_filter_check_discard(struct trace_event_call *call, void *rec,  	return 0;  } -void trace_free_pid_list(struct trace_pid_list *pid_list) -{ -	vfree(pid_list->pids); -	kfree(pid_list); -} -  /**   * trace_find_filtered_pid - check if a pid exists in a filtered_pid list   * @filtered_pids: The list of pids to check @@ -528,14 +522,7 @@ void trace_free_pid_list(struct trace_pid_list *pid_list)  bool  trace_find_filtered_pid(struct trace_pid_list *filtered_pids, pid_t search_pid)  { -	/* -	 * If pid_max changed after filtered_pids was created, we -	 * by default ignore all pids greater than the previous pid_max. -	 */ -	if (search_pid >= filtered_pids->pid_max) -		return false; - -	return test_bit(search_pid, filtered_pids->pids); +	return trace_pid_list_is_set(filtered_pids, search_pid);  }  /** @@ -592,15 +579,11 @@ void trace_filter_add_remove_task(struct trace_pid_list *pid_list,  			return;  	} -	/* Sorry, but we don't support pid_max changing after setting */ -	if (task->pid >= pid_list->pid_max) -		return; -  	/* "self" is set for forks, and NULL for exits */  	if (self) -		set_bit(task->pid, pid_list->pids); +		trace_pid_list_set(pid_list, task->pid);  	else -		clear_bit(task->pid, pid_list->pids); +		trace_pid_list_clear(pid_list, task->pid);  }  /** @@ -617,18 +600,19 @@ void trace_filter_add_remove_task(struct trace_pid_list *pid_list,   */  void *trace_pid_next(struct trace_pid_list *pid_list, void *v, loff_t *pos)  { -	unsigned long pid = (unsigned long)v; +	long pid = (unsigned long)v; +	unsigned int next;  	(*pos)++;  	/* pid already is +1 of the actual previous bit */ -	pid = find_next_bit(pid_list->pids, pid_list->pid_max, pid); +	if (trace_pid_list_next(pid_list, pid, &next) < 0) +		return NULL; -	/* Return pid + 1 to allow zero to be represented */ -	if (pid < pid_list->pid_max) -		return (void *)(pid + 1); +	pid = next; -	return NULL; +	/* Return pid + 1 to allow zero to be represented */ +	return (void *)(pid + 1);  }  /** @@ -645,12 +629,14 @@ void *trace_pid_next(struct trace_pid_list *pid_list, void *v, loff_t *pos)  void *trace_pid_start(struct trace_pid_list *pid_list, loff_t *pos)  {  	unsigned long pid; +	unsigned int first;  	loff_t l = 0; -	pid = find_first_bit(pid_list->pids, pid_list->pid_max); -	if (pid >= pid_list->pid_max) +	if (trace_pid_list_first(pid_list, &first) < 0)  		return NULL; +	pid = first; +  	/* Return pid + 1 so that zero can be the exit value */  	for (pid++; pid && l < *pos;  	     pid = (unsigned long)trace_pid_next(pid_list, (void *)pid, &l)) @@ -686,7 +672,7 @@ int trace_pid_write(struct trace_pid_list *filtered_pids,  	unsigned long val;  	int nr_pids = 0;  	ssize_t read = 0; -	ssize_t ret = 0; +	ssize_t ret;  	loff_t pos;  	pid_t pid; @@ -699,34 +685,23 @@ int trace_pid_write(struct trace_pid_list *filtered_pids,  	 * the user. If the operation fails, then the current list is  	 * not modified.  	 */ -	pid_list = kmalloc(sizeof(*pid_list), GFP_KERNEL); +	pid_list = trace_pid_list_alloc();  	if (!pid_list) {  		trace_parser_put(&parser);  		return -ENOMEM;  	} -	pid_list->pid_max = READ_ONCE(pid_max); - -	/* Only truncating will shrink pid_max */ -	if (filtered_pids && filtered_pids->pid_max > pid_list->pid_max) -		pid_list->pid_max = filtered_pids->pid_max; - -	pid_list->pids = vzalloc((pid_list->pid_max + 7) >> 3); -	if (!pid_list->pids) { -		trace_parser_put(&parser); -		kfree(pid_list); -		return -ENOMEM; -	} -  	if (filtered_pids) {  		/* copy the current bits to the new max */ -		for_each_set_bit(pid, filtered_pids->pids, -				 filtered_pids->pid_max) { -			set_bit(pid, pid_list->pids); +		ret = trace_pid_list_first(filtered_pids, &pid); +		while (!ret) { +			trace_pid_list_set(pid_list, pid); +			ret = trace_pid_list_next(filtered_pids, pid + 1, &pid);  			nr_pids++;  		}  	} +	ret = 0;  	while (cnt > 0) {  		pos = 0; @@ -742,12 +717,13 @@ int trace_pid_write(struct trace_pid_list *filtered_pids,  		ret = -EINVAL;  		if (kstrtoul(parser.buffer, 0, &val))  			break; -		if (val >= pid_list->pid_max) -			break;  		pid = (pid_t)val; -		set_bit(pid, pid_list->pids); +		if (trace_pid_list_set(pid_list, pid) < 0) { +			ret = -1; +			break; +		}  		nr_pids++;  		trace_parser_clear(&parser); @@ -756,13 +732,13 @@ int trace_pid_write(struct trace_pid_list *filtered_pids,  	trace_parser_put(&parser);  	if (ret < 0) { -		trace_free_pid_list(pid_list); +		trace_pid_list_free(pid_list);  		return ret;  	}  	if (!nr_pids) {  		/* Cleared the list of pids */ -		trace_free_pid_list(pid_list); +		trace_pid_list_free(pid_list);  		read = ret;  		pid_list = NULL;  	} @@ -1714,7 +1690,8 @@ static void trace_create_maxlat_file(struct trace_array *tr,  {  	INIT_WORK(&tr->fsnotify_work, latency_fsnotify_workfn);  	init_irq_work(&tr->fsnotify_irqwork, latency_fsnotify_workfn_irq); -	tr->d_max_latency = trace_create_file("tracing_max_latency", 0644, +	tr->d_max_latency = trace_create_file("tracing_max_latency", +					      TRACE_MODE_WRITE,  					      d_tracer, &tr->max_latency,  					      &tracing_max_lat_fops);  } @@ -1744,16 +1721,15 @@ void latency_fsnotify(struct trace_array *tr)  	irq_work_queue(&tr->fsnotify_irqwork);  } -/* - * (defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)) && \ - *  defined(CONFIG_FSNOTIFY) - */ -#else +#elif defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)	\ +	|| defined(CONFIG_OSNOISE_TRACER)  #define trace_create_maxlat_file(tr, d_tracer)				\ -	trace_create_file("tracing_max_latency", 0644, d_tracer,	\ -			  &tr->max_latency, &tracing_max_lat_fops) +	trace_create_file("tracing_max_latency", TRACE_MODE_WRITE,	\ +			  d_tracer, &tr->max_latency, &tracing_max_lat_fops) +#else +#define trace_create_maxlat_file(tr, d_tracer)	 do { } while (0)  #endif  #ifdef CONFIG_TRACER_MAX_TRACE @@ -5629,6 +5605,7 @@ static const char readme_msg[] =  #ifdef CONFIG_HIST_TRIGGERS  	"      hist trigger\t- If set, event hits are aggregated into a hash table\n"  	"\t    Format: hist:keys=<field1[,field2,...]>\n" +	"\t            [:<var1>=<field|var_ref|numeric_literal>[,<var2>=...]]\n"  	"\t            [:values=<field1[,field2,...]>]\n"  	"\t            [:sort=<field1[,field2,...]>]\n"  	"\t            [:size=#entries]\n" @@ -5640,6 +5617,16 @@ static const char readme_msg[] =  	"\t            common_timestamp - to record current timestamp\n"  	"\t            common_cpu - to record the CPU the event happened on\n"  	"\n" +	"\t    A hist trigger variable can be:\n" +	"\t        - a reference to a field e.g. x=current_timestamp,\n" +	"\t        - a reference to another variable e.g. y=$x,\n" +	"\t        - a numeric literal: e.g. ms_per_sec=1000,\n" +	"\t        - an arithmetic expression: e.g. time_secs=current_timestamp/1000\n" +	"\n" +	"\t    hist trigger aritmethic expressions support addition(+), subtraction(-),\n" +	"\t    multiplication(*) and division(/) operators. An operand can be either a\n" +	"\t    variable reference, field or numeric literal.\n" +	"\n"  	"\t    When a matching event is hit, an entry is added to a hash\n"  	"\t    table using the key(s) and value(s) named, and the value of a\n"  	"\t    sum called 'hitcount' is incremented.  Keys and values\n" @@ -6078,7 +6065,7 @@ trace_insert_eval_map_file(struct module *mod, struct trace_eval_map **start,  static void trace_create_eval_file(struct dentry *d_tracer)  { -	trace_create_file("eval_map", 0444, d_tracer, +	trace_create_file("eval_map", TRACE_MODE_READ, d_tracer,  			  NULL, &tracing_eval_map_fops);  } @@ -8591,27 +8578,27 @@ tracing_init_tracefs_percpu(struct trace_array *tr, long cpu)  	}  	/* per cpu trace_pipe */ -	trace_create_cpu_file("trace_pipe", 0444, d_cpu, +	trace_create_cpu_file("trace_pipe", TRACE_MODE_READ, d_cpu,  				tr, cpu, &tracing_pipe_fops);  	/* per cpu trace */ -	trace_create_cpu_file("trace", 0644, d_cpu, +	trace_create_cpu_file("trace", TRACE_MODE_WRITE, d_cpu,  				tr, cpu, &tracing_fops); -	trace_create_cpu_file("trace_pipe_raw", 0444, d_cpu, +	trace_create_cpu_file("trace_pipe_raw", TRACE_MODE_READ, d_cpu,  				tr, cpu, &tracing_buffers_fops); -	trace_create_cpu_file("stats", 0444, d_cpu, +	trace_create_cpu_file("stats", TRACE_MODE_READ, d_cpu,  				tr, cpu, &tracing_stats_fops); -	trace_create_cpu_file("buffer_size_kb", 0444, d_cpu, +	trace_create_cpu_file("buffer_size_kb", TRACE_MODE_READ, d_cpu,  				tr, cpu, &tracing_entries_fops);  #ifdef CONFIG_TRACER_SNAPSHOT -	trace_create_cpu_file("snapshot", 0644, d_cpu, +	trace_create_cpu_file("snapshot", TRACE_MODE_WRITE, d_cpu,  				tr, cpu, &snapshot_fops); -	trace_create_cpu_file("snapshot_raw", 0444, d_cpu, +	trace_create_cpu_file("snapshot_raw", TRACE_MODE_READ, d_cpu,  				tr, cpu, &snapshot_raw_fops);  #endif  } @@ -8817,8 +8804,8 @@ create_trace_option_file(struct trace_array *tr,  	topt->opt = opt;  	topt->tr = tr; -	topt->entry = trace_create_file(opt->name, 0644, t_options, topt, -				    &trace_options_fops); +	topt->entry = trace_create_file(opt->name, TRACE_MODE_WRITE, +					t_options, topt, &trace_options_fops);  } @@ -8893,7 +8880,7 @@ create_trace_option_core_file(struct trace_array *tr,  	if (!t_options)  		return NULL; -	return trace_create_file(option, 0644, t_options, +	return trace_create_file(option, TRACE_MODE_WRITE, t_options,  				 (void *)&tr->trace_flags_index[index],  				 &trace_options_core_fops);  } @@ -9418,28 +9405,28 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)  	struct trace_event_file *file;  	int cpu; -	trace_create_file("available_tracers", 0444, d_tracer, +	trace_create_file("available_tracers", TRACE_MODE_READ, d_tracer,  			tr, &show_traces_fops); -	trace_create_file("current_tracer", 0644, d_tracer, +	trace_create_file("current_tracer", TRACE_MODE_WRITE, d_tracer,  			tr, &set_tracer_fops); -	trace_create_file("tracing_cpumask", 0644, d_tracer, +	trace_create_file("tracing_cpumask", TRACE_MODE_WRITE, d_tracer,  			  tr, &tracing_cpumask_fops); -	trace_create_file("trace_options", 0644, d_tracer, +	trace_create_file("trace_options", TRACE_MODE_WRITE, d_tracer,  			  tr, &tracing_iter_fops); -	trace_create_file("trace", 0644, d_tracer, +	trace_create_file("trace", TRACE_MODE_WRITE, d_tracer,  			  tr, &tracing_fops); -	trace_create_file("trace_pipe", 0444, d_tracer, +	trace_create_file("trace_pipe", TRACE_MODE_READ, d_tracer,  			  tr, &tracing_pipe_fops); -	trace_create_file("buffer_size_kb", 0644, d_tracer, +	trace_create_file("buffer_size_kb", TRACE_MODE_WRITE, d_tracer,  			  tr, &tracing_entries_fops); -	trace_create_file("buffer_total_size_kb", 0444, d_tracer, +	trace_create_file("buffer_total_size_kb", TRACE_MODE_READ, d_tracer,  			  tr, &tracing_total_entries_fops);  	trace_create_file("free_buffer", 0200, d_tracer, @@ -9450,42 +9437,40 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)  	file = __find_event_file(tr, "ftrace", "print");  	if (file && file->dir) -		trace_create_file("trigger", 0644, file->dir, file, -				  &event_trigger_fops); +		trace_create_file("trigger", TRACE_MODE_WRITE, file->dir, +				  file, &event_trigger_fops);  	tr->trace_marker_file = file;  	trace_create_file("trace_marker_raw", 0220, d_tracer,  			  tr, &tracing_mark_raw_fops); -	trace_create_file("trace_clock", 0644, d_tracer, tr, +	trace_create_file("trace_clock", TRACE_MODE_WRITE, d_tracer, tr,  			  &trace_clock_fops); -	trace_create_file("tracing_on", 0644, d_tracer, +	trace_create_file("tracing_on", TRACE_MODE_WRITE, d_tracer,  			  tr, &rb_simple_fops); -	trace_create_file("timestamp_mode", 0444, d_tracer, tr, +	trace_create_file("timestamp_mode", TRACE_MODE_READ, d_tracer, tr,  			  &trace_time_stamp_mode_fops);  	tr->buffer_percent = 50; -	trace_create_file("buffer_percent", 0444, d_tracer, +	trace_create_file("buffer_percent", TRACE_MODE_READ, d_tracer,  			tr, &buffer_percent_fops);  	create_trace_options_dir(tr); -#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)  	trace_create_maxlat_file(tr, d_tracer); -#endif  	if (ftrace_create_function_files(tr, d_tracer))  		MEM_FAIL(1, "Could not allocate function filter files");  #ifdef CONFIG_TRACER_SNAPSHOT -	trace_create_file("snapshot", 0644, d_tracer, +	trace_create_file("snapshot", TRACE_MODE_WRITE, d_tracer,  			  tr, &snapshot_fops);  #endif -	trace_create_file("error_log", 0644, d_tracer, +	trace_create_file("error_log", TRACE_MODE_WRITE, d_tracer,  			  tr, &tracing_err_log_fops);  	for_each_tracing_cpu(cpu) @@ -9678,19 +9663,19 @@ static __init int tracer_init_tracefs(void)  	init_tracer_tracefs(&global_trace, NULL);  	ftrace_init_tracefs_toplevel(&global_trace, NULL); -	trace_create_file("tracing_thresh", 0644, NULL, +	trace_create_file("tracing_thresh", TRACE_MODE_WRITE, NULL,  			&global_trace, &tracing_thresh_fops); -	trace_create_file("README", 0444, NULL, +	trace_create_file("README", TRACE_MODE_READ, NULL,  			NULL, &tracing_readme_fops); -	trace_create_file("saved_cmdlines", 0444, NULL, +	trace_create_file("saved_cmdlines", TRACE_MODE_READ, NULL,  			NULL, &tracing_saved_cmdlines_fops); -	trace_create_file("saved_cmdlines_size", 0644, NULL, +	trace_create_file("saved_cmdlines_size", TRACE_MODE_WRITE, NULL,  			  NULL, &tracing_saved_cmdlines_size_fops); -	trace_create_file("saved_tgids", 0444, NULL, +	trace_create_file("saved_tgids", TRACE_MODE_READ, NULL,  			NULL, &tracing_saved_tgids_fops);  	trace_eval_init(); @@ -9702,7 +9687,7 @@ static __init int tracer_init_tracefs(void)  #endif  #ifdef CONFIG_DYNAMIC_FTRACE -	trace_create_file("dyn_ftrace_total_info", 0444, NULL, +	trace_create_file("dyn_ftrace_total_info", TRACE_MODE_READ, NULL,  			NULL, &tracing_dyn_info_fops);  #endif |