aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
authorSteven Rostedt (VMware) <rostedt@goodmis.org>2017-04-19 22:39:44 -0400
committerSteven Rostedt (VMware) <rostedt@goodmis.org>2017-04-20 22:06:46 -0400
commit6e4443199e5354255e8a4c1e8e5cfc8ef064c3ce (patch)
treeb0e7181d739a1207606bce8f60be5f305e27ea6b /kernel/trace/trace.c
parent7b60f3d8761561d95d7e962522d6338143fc2329 (diff)
tracing/ftrace: Add a better way to pass data via the probe functions
With the redesign of the registration and execution of the function probes (triggers), data can now be passed from the setup of the probe to the probe callers that are specific to the trace_array it is on. Although, all probes still only affect the toplevel trace array, this change will allow for instances to have their own probes separated from other instances and the top array. That is, something like the stacktrace probe can be set to trace only in an instance and not the toplevel trace array. This isn't implement yet, but this change sets the ground work for the change. When a probe callback is triggered (someone writes the probe format into set_ftrace_filter), it calls register_ftrace_function_probe() passing in init_data that will be used to initialize the probe. Then for every matching function, register_ftrace_function_probe() will call the probe_ops->init() function with the init data that was passed to it, as well as an address to a place holder that is associated with the probe and the instance. The first occurrence will have a NULL in the pointer. The init() function will then initialize it. If other probes are added, or more functions are part of the probe, the place holder will be passed to the init() function with the place holder data that it was initialized to the last time. Then this place_holder is passed to each of the other probe_ops functions, where it can be used in the function callback. When the probe_ops free() function is called, it can be called either with the rip of the function that is being removed from the probe, or zero, indicating that there are no more functions attached to the probe, and the place holder is about to be freed. This gives the probe_ops a way to free the data it assigned to the place holder if it was allocade during the first init call. Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index e61610e5e6e3..18256cd7ad2c 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -6737,7 +6737,7 @@ static const struct file_operations tracing_dyn_info_fops = {
6737static void 6737static void
6738ftrace_snapshot(unsigned long ip, unsigned long parent_ip, 6738ftrace_snapshot(unsigned long ip, unsigned long parent_ip,
6739 struct trace_array *tr, struct ftrace_probe_ops *ops, 6739 struct trace_array *tr, struct ftrace_probe_ops *ops,
6740 void **data) 6740 void *data)
6741{ 6741{
6742 tracing_snapshot(); 6742 tracing_snapshot();
6743} 6743}
@@ -6745,9 +6745,9 @@ ftrace_snapshot(unsigned long ip, unsigned long parent_ip,
6745static void 6745static void
6746ftrace_count_snapshot(unsigned long ip, unsigned long parent_ip, 6746ftrace_count_snapshot(unsigned long ip, unsigned long parent_ip,
6747 struct trace_array *tr, struct ftrace_probe_ops *ops, 6747 struct trace_array *tr, struct ftrace_probe_ops *ops,
6748 void **data) 6748 void *data)
6749{ 6749{
6750 struct ftrace_func_mapper *mapper = ops->private_data; 6750 struct ftrace_func_mapper *mapper = data;
6751 long *count = NULL; 6751 long *count = NULL;
6752 6752
6753 if (mapper) 6753 if (mapper)
@@ -6768,7 +6768,7 @@ static int
6768ftrace_snapshot_print(struct seq_file *m, unsigned long ip, 6768ftrace_snapshot_print(struct seq_file *m, unsigned long ip,
6769 struct ftrace_probe_ops *ops, void *data) 6769 struct ftrace_probe_ops *ops, void *data)
6770{ 6770{
6771 struct ftrace_func_mapper *mapper = ops->private_data; 6771 struct ftrace_func_mapper *mapper = data;
6772 long *count = NULL; 6772 long *count = NULL;
6773 6773
6774 seq_printf(m, "%ps:", (void *)ip); 6774 seq_printf(m, "%ps:", (void *)ip);
@@ -6788,18 +6788,32 @@ ftrace_snapshot_print(struct seq_file *m, unsigned long ip,
6788 6788
6789static int 6789static int
6790ftrace_snapshot_init(struct ftrace_probe_ops *ops, struct trace_array *tr, 6790ftrace_snapshot_init(struct ftrace_probe_ops *ops, struct trace_array *tr,
6791 unsigned long ip, void *data) 6791 unsigned long ip, void *init_data, void **data)
6792{ 6792{
6793 struct ftrace_func_mapper *mapper = ops->private_data; 6793 struct ftrace_func_mapper *mapper = *data;
6794
6795 if (!mapper) {
6796 mapper = allocate_ftrace_func_mapper();
6797 if (!mapper)
6798 return -ENOMEM;
6799 *data = mapper;
6800 }
6794 6801
6795 return ftrace_func_mapper_add_ip(mapper, ip, data); 6802 return ftrace_func_mapper_add_ip(mapper, ip, init_data);
6796} 6803}
6797 6804
6798static void 6805static void
6799ftrace_snapshot_free(struct ftrace_probe_ops *ops, struct trace_array *tr, 6806ftrace_snapshot_free(struct ftrace_probe_ops *ops, struct trace_array *tr,
6800 unsigned long ip, void **data) 6807 unsigned long ip, void *data)
6801{ 6808{
6802 struct ftrace_func_mapper *mapper = ops->private_data; 6809 struct ftrace_func_mapper *mapper = data;
6810
6811 if (!ip) {
6812 if (!mapper)
6813 return;
6814 free_ftrace_func_mapper(mapper, NULL);
6815 return;
6816 }
6803 6817
6804 ftrace_func_mapper_remove_ip(mapper, ip); 6818 ftrace_func_mapper_remove_ip(mapper, ip);
6805} 6819}
@@ -6842,12 +6856,6 @@ ftrace_trace_snapshot_callback(struct trace_array *tr, struct ftrace_hash *hash,
6842 if (!strlen(number)) 6856 if (!strlen(number))
6843 goto out_reg; 6857 goto out_reg;
6844 6858
6845 if (!ops->private_data) {
6846 ops->private_data = allocate_ftrace_func_mapper();
6847 if (!ops->private_data)
6848 return -ENOMEM;
6849 }
6850
6851 /* 6859 /*
6852 * We use the callback data field (which is a pointer) 6860 * We use the callback data field (which is a pointer)
6853 * as our counter. 6861 * as our counter.