diff options
author | Steven Rostedt (VMware) <rostedt@goodmis.org> | 2017-04-03 20:58:35 -0400 |
---|---|---|
committer | Steven Rostedt (VMware) <rostedt@goodmis.org> | 2017-04-20 22:06:37 -0400 |
commit | 41794f190780c28784fa62b22001691e5876d149 (patch) | |
tree | 6352cf32223ea0228c9c051e0f1acb6c0984a4f5 /kernel/trace/trace_events.c | |
parent | bca6c8d0480a8aa5c86f8f416db96c71f6b79e29 (diff) | |
download | blackbird-op-linux-41794f190780c28784fa62b22001691e5876d149.tar.gz blackbird-op-linux-41794f190780c28784fa62b22001691e5876d149.zip |
ftrace: Added ftrace_func_mapper for function probe triggers
In order to move the ops to the function probes directly, they need a way to
map function ips to their own data without depending on the infrastructure
of the function probes, as the data field will be going away.
New helper functions are added that are based on the ftrace_hash code.
ftrace_func_mapper functions are there to let the probes map ips to their
data. These can be allocated by the probe ops, and referenced in the
function callbacks.
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/trace_events.c')
-rw-r--r-- | kernel/trace/trace_events.c | 70 |
1 files changed, 55 insertions, 15 deletions
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 9dbac1881b03..ee308312fe87 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -2460,32 +2460,44 @@ struct event_probe_data { bool enable; }; +static void update_event_probe(struct event_probe_data *data) +{ + if (data->enable) + clear_bit(EVENT_FILE_FL_SOFT_DISABLED_BIT, &data->file->flags); + else + set_bit(EVENT_FILE_FL_SOFT_DISABLED_BIT, &data->file->flags); +} + static void event_enable_probe(unsigned long ip, unsigned long parent_ip, struct ftrace_probe_ops *ops, void **_data) { - struct event_probe_data **pdata = (struct event_probe_data **)_data; - struct event_probe_data *data = *pdata; + struct ftrace_func_mapper *mapper = ops->private_data; + struct event_probe_data *data; + void **pdata; - if (!data) + pdata = ftrace_func_mapper_find_ip(mapper, ip); + if (!pdata || !*pdata) return; - if (data->enable) - clear_bit(EVENT_FILE_FL_SOFT_DISABLED_BIT, &data->file->flags); - else - set_bit(EVENT_FILE_FL_SOFT_DISABLED_BIT, &data->file->flags); + data = *pdata; + update_event_probe(data); } static void event_enable_count_probe(unsigned long ip, unsigned long parent_ip, struct ftrace_probe_ops *ops, void **_data) { - struct event_probe_data **pdata = (struct event_probe_data **)_data; - struct event_probe_data *data = *pdata; + struct ftrace_func_mapper *mapper = ops->private_data; + struct event_probe_data *data; + void **pdata; - if (!data) + pdata = ftrace_func_mapper_find_ip(mapper, ip); + if (!pdata || !*pdata) return; + data = *pdata; + if (!data->count) return; @@ -2496,14 +2508,23 @@ event_enable_count_probe(unsigned long ip, unsigned long parent_ip, if (data->count != -1) (data->count)--; - event_enable_probe(ip, parent_ip, ops, _data); + update_event_probe(data); } static int event_enable_print(struct seq_file *m, unsigned long ip, struct ftrace_probe_ops *ops, void *_data) { - struct event_probe_data *data = _data; + struct ftrace_func_mapper *mapper = ops->private_data; + struct event_probe_data *data; + void **pdata; + + pdata = ftrace_func_mapper_find_ip(mapper, ip); + + if (WARN_ON_ONCE(!pdata || !*pdata)) + return 0; + + data = *pdata; seq_printf(m, "%ps:", (void *)ip); @@ -2524,10 +2545,17 @@ static int event_enable_init(struct ftrace_probe_ops *ops, unsigned long ip, void **_data) { + struct ftrace_func_mapper *mapper = ops->private_data; struct event_probe_data **pdata = (struct event_probe_data **)_data; struct event_probe_data *data = *pdata; + int ret; + + ret = ftrace_func_mapper_add_ip(mapper, ip, data); + if (ret < 0) + return ret; data->ref++; + return 0; } @@ -2535,8 +2563,13 @@ static void event_enable_free(struct ftrace_probe_ops *ops, unsigned long ip, void **_data) { - struct event_probe_data **pdata = (struct event_probe_data **)_data; - struct event_probe_data *data = *pdata; + struct ftrace_func_mapper *mapper = ops->private_data; + struct event_probe_data *data; + + data = ftrace_func_mapper_remove_ip(mapper, ip); + + if (WARN_ON_ONCE(!data)) + return; if (WARN_ON_ONCE(data->ref <= 0)) return; @@ -2548,7 +2581,6 @@ event_enable_free(struct ftrace_probe_ops *ops, unsigned long ip, module_put(data->file->event_call->mod); kfree(data); } - *pdata = NULL; } static struct ftrace_probe_ops event_enable_probe_ops = { @@ -2627,6 +2659,13 @@ event_enable_func(struct ftrace_hash *hash, } ret = -ENOMEM; + + if (!ops->private_data) { + ops->private_data = allocate_ftrace_func_mapper(); + if (!ops->private_data) + goto out; + } + data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) goto out; @@ -2663,6 +2702,7 @@ event_enable_func(struct ftrace_hash *hash, ret = __ftrace_event_enable_disable(file, 1, 1); if (ret < 0) goto out_put; + ret = register_ftrace_function_probe(glob, ops, data); /* * The above returns on success the # of functions enabled, |