summaryrefslogtreecommitdiff
path: root/kernel/trace/ftrace.c
diff options
context:
space:
mode:
authorSteven Rostedt (VMware) <rostedt@goodmis.org>2017-04-05 13:12:55 -0400
committerSteven Rostedt (VMware) <rostedt@goodmis.org>2017-04-20 22:06:45 -0400
commit04ec7bb642b77374b53731b795b5654b5aff1c00 (patch)
treed1207b1237a6ba31feb057130af1279e43d962c1 /kernel/trace/ftrace.c
parent8d70725e452cac9796e9025ccd79c45ffcc4d109 (diff)
tracing: Have the trace_array hold the list of registered func probes
Add a link list to the trace_array to hold func probes that are registered. Currently, all function probes are the same for all instances as it was before, that is, only the top level trace_array holds the function probes. But this lays the ground work to have function probes be attached to individual instances, and having the event trigger only affect events in the given instance. But that work is still to be done. Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r--kernel/trace/ftrace.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 8394055e6793..ea208e93f000 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1096,8 +1096,6 @@ static bool update_all_ops;
# error Dynamic ftrace depends on MCOUNT_RECORD
#endif
-static LIST_HEAD(ftrace_func_probes);
-
struct ftrace_func_entry {
struct hlist_node hlist;
unsigned long ip;
@@ -3070,6 +3068,8 @@ static void *
t_probe_next(struct seq_file *m, loff_t *pos)
{
struct ftrace_iterator *iter = m->private;
+ struct trace_array *tr = global_ops.private;
+ struct list_head *func_probes;
struct ftrace_hash *hash;
struct list_head *next;
struct hlist_node *hnd = NULL;
@@ -3079,11 +3079,15 @@ t_probe_next(struct seq_file *m, loff_t *pos)
(*pos)++;
iter->pos = *pos;
- if (list_empty(&ftrace_func_probes))
+ if (!tr)
+ return NULL;
+
+ func_probes = &tr->func_probes;
+ if (list_empty(func_probes))
return NULL;
if (!iter->probe) {
- next = ftrace_func_probes.next;
+ next = func_probes->next;
iter->probe = list_entry(next, struct ftrace_probe_ops, list);
}
@@ -3095,7 +3099,7 @@ t_probe_next(struct seq_file *m, loff_t *pos)
retry:
if (iter->pidx >= size) {
- if (iter->probe->list.next == &ftrace_func_probes)
+ if (iter->probe->list.next == func_probes)
return NULL;
next = iter->probe->list.next;
iter->probe = list_entry(next, struct ftrace_probe_ops, list);
@@ -3752,7 +3756,7 @@ static int ftrace_hash_move_and_update_ops(struct ftrace_ops *ops,
*/
static int
-ftrace_mod_callback(struct ftrace_hash *hash,
+ftrace_mod_callback(struct trace_array *tr, struct ftrace_hash *hash,
char *func, char *cmd, char *module, int enable)
{
int ret;
@@ -3942,8 +3946,8 @@ void free_ftrace_func_mapper(struct ftrace_func_mapper *mapper,
}
int
-register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
- void *data)
+register_ftrace_function_probe(char *glob, struct trace_array *tr,
+ struct ftrace_probe_ops *ops, void *data)
{
struct ftrace_func_entry *entry;
struct ftrace_hash **orig_hash;
@@ -3954,6 +3958,9 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
int ret;
int i;
+ if (WARN_ON(!tr))
+ return -EINVAL;
+
/* We do not support '!' for function probes */
if (WARN_ON(glob[0] == '!'))
return -EINVAL;
@@ -4006,7 +4013,7 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
goto err_unlock;
if (list_empty(&ops->list))
- list_add(&ops->list, &ftrace_func_probes);
+ list_add(&ops->list, &tr->func_probes);
if (!(ops->ops.flags & FTRACE_OPS_FL_ENABLED))
ret = ftrace_startup(&ops->ops, 0);
@@ -4192,9 +4199,11 @@ __init int unregister_ftrace_command(struct ftrace_func_command *cmd)
return ret;
}
-static int ftrace_process_regex(struct ftrace_hash *hash,
+static int ftrace_process_regex(struct ftrace_iterator *iter,
char *buff, int len, int enable)
{
+ struct ftrace_hash *hash = iter->hash;
+ struct trace_array *tr = global_ops.private;
char *func, *command, *next = buff;
struct ftrace_func_command *p;
int ret = -EINVAL;
@@ -4214,10 +4223,13 @@ static int ftrace_process_regex(struct ftrace_hash *hash,
command = strsep(&next, ":");
+ if (WARN_ON_ONCE(!tr))
+ return -EINVAL;
+
mutex_lock(&ftrace_cmd_mutex);
list_for_each_entry(p, &ftrace_commands, list) {
if (strcmp(p->name, command) == 0) {
- ret = p->func(hash, func, command, next, enable);
+ ret = p->func(tr, hash, func, command, next, enable);
goto out_unlock;
}
}
@@ -4254,7 +4266,7 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
if (read >= 0 && trace_parser_loaded(parser) &&
!trace_parser_cont(parser)) {
- ret = ftrace_process_regex(iter->hash, parser->buffer,
+ ret = ftrace_process_regex(iter, parser->buffer,
parser->idx, enable);
trace_parser_clear(parser);
if (ret < 0)
@@ -5441,6 +5453,10 @@ static void ftrace_update_trampoline(struct ftrace_ops *ops)
arch_ftrace_update_trampoline(ops);
}
+void ftrace_init_trace_array(struct trace_array *tr)
+{
+ INIT_LIST_HEAD(&tr->func_probes);
+}
#else
static struct ftrace_ops global_ops = {
@@ -5495,6 +5511,7 @@ __init void ftrace_init_global_array_ops(struct trace_array *tr)
{
tr->ops = &global_ops;
tr->ops->private = tr;
+ ftrace_init_trace_array(tr);
}
void ftrace_init_array_ops(struct trace_array *tr, ftrace_func_t func)