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: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
parent 8d70725e
...@@ -1096,8 +1096,6 @@ static bool update_all_ops; ...@@ -1096,8 +1096,6 @@ static bool update_all_ops;
# error Dynamic ftrace depends on MCOUNT_RECORD # error Dynamic ftrace depends on MCOUNT_RECORD
#endif #endif
static LIST_HEAD(ftrace_func_probes);
struct ftrace_func_entry { struct ftrace_func_entry {
struct hlist_node hlist; struct hlist_node hlist;
unsigned long ip; unsigned long ip;
...@@ -3070,6 +3068,8 @@ static void * ...@@ -3070,6 +3068,8 @@ static void *
t_probe_next(struct seq_file *m, loff_t *pos) t_probe_next(struct seq_file *m, loff_t *pos)
{ {
struct ftrace_iterator *iter = m->private; struct ftrace_iterator *iter = m->private;
struct trace_array *tr = global_ops.private;
struct list_head *func_probes;
struct ftrace_hash *hash; struct ftrace_hash *hash;
struct list_head *next; struct list_head *next;
struct hlist_node *hnd = NULL; struct hlist_node *hnd = NULL;
...@@ -3079,11 +3079,15 @@ t_probe_next(struct seq_file *m, loff_t *pos) ...@@ -3079,11 +3079,15 @@ t_probe_next(struct seq_file *m, loff_t *pos)
(*pos)++; (*pos)++;
iter->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; return NULL;
if (!iter->probe) { if (!iter->probe) {
next = ftrace_func_probes.next; next = func_probes->next;
iter->probe = list_entry(next, struct ftrace_probe_ops, list); iter->probe = list_entry(next, struct ftrace_probe_ops, list);
} }
...@@ -3095,7 +3099,7 @@ t_probe_next(struct seq_file *m, loff_t *pos) ...@@ -3095,7 +3099,7 @@ t_probe_next(struct seq_file *m, loff_t *pos)
retry: retry:
if (iter->pidx >= size) { if (iter->pidx >= size) {
if (iter->probe->list.next == &ftrace_func_probes) if (iter->probe->list.next == func_probes)
return NULL; return NULL;
next = iter->probe->list.next; next = iter->probe->list.next;
iter->probe = list_entry(next, struct ftrace_probe_ops, list); 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, ...@@ -3752,7 +3756,7 @@ static int ftrace_hash_move_and_update_ops(struct ftrace_ops *ops,
*/ */
static int 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) char *func, char *cmd, char *module, int enable)
{ {
int ret; int ret;
...@@ -3942,8 +3946,8 @@ void free_ftrace_func_mapper(struct ftrace_func_mapper *mapper, ...@@ -3942,8 +3946,8 @@ void free_ftrace_func_mapper(struct ftrace_func_mapper *mapper,
} }
int int
register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, register_ftrace_function_probe(char *glob, struct trace_array *tr,
void *data) struct ftrace_probe_ops *ops, void *data)
{ {
struct ftrace_func_entry *entry; struct ftrace_func_entry *entry;
struct ftrace_hash **orig_hash; struct ftrace_hash **orig_hash;
...@@ -3954,6 +3958,9 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, ...@@ -3954,6 +3958,9 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
int ret; int ret;
int i; int i;
if (WARN_ON(!tr))
return -EINVAL;
/* We do not support '!' for function probes */ /* We do not support '!' for function probes */
if (WARN_ON(glob[0] == '!')) if (WARN_ON(glob[0] == '!'))
return -EINVAL; return -EINVAL;
...@@ -4006,7 +4013,7 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, ...@@ -4006,7 +4013,7 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
goto err_unlock; goto err_unlock;
if (list_empty(&ops->list)) 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)) if (!(ops->ops.flags & FTRACE_OPS_FL_ENABLED))
ret = ftrace_startup(&ops->ops, 0); ret = ftrace_startup(&ops->ops, 0);
...@@ -4192,9 +4199,11 @@ __init int unregister_ftrace_command(struct ftrace_func_command *cmd) ...@@ -4192,9 +4199,11 @@ __init int unregister_ftrace_command(struct ftrace_func_command *cmd)
return ret; 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) char *buff, int len, int enable)
{ {
struct ftrace_hash *hash = iter->hash;
struct trace_array *tr = global_ops.private;
char *func, *command, *next = buff; char *func, *command, *next = buff;
struct ftrace_func_command *p; struct ftrace_func_command *p;
int ret = -EINVAL; int ret = -EINVAL;
...@@ -4214,10 +4223,13 @@ static int ftrace_process_regex(struct ftrace_hash *hash, ...@@ -4214,10 +4223,13 @@ static int ftrace_process_regex(struct ftrace_hash *hash,
command = strsep(&next, ":"); command = strsep(&next, ":");
if (WARN_ON_ONCE(!tr))
return -EINVAL;
mutex_lock(&ftrace_cmd_mutex); mutex_lock(&ftrace_cmd_mutex);
list_for_each_entry(p, &ftrace_commands, list) { list_for_each_entry(p, &ftrace_commands, list) {
if (strcmp(p->name, command) == 0) { 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; goto out_unlock;
} }
} }
...@@ -4254,7 +4266,7 @@ ftrace_regex_write(struct file *file, const char __user *ubuf, ...@@ -4254,7 +4266,7 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
if (read >= 0 && trace_parser_loaded(parser) && if (read >= 0 && trace_parser_loaded(parser) &&
!trace_parser_cont(parser)) { !trace_parser_cont(parser)) {
ret = ftrace_process_regex(iter->hash, parser->buffer, ret = ftrace_process_regex(iter, parser->buffer,
parser->idx, enable); parser->idx, enable);
trace_parser_clear(parser); trace_parser_clear(parser);
if (ret < 0) if (ret < 0)
...@@ -5441,6 +5453,10 @@ static void ftrace_update_trampoline(struct ftrace_ops *ops) ...@@ -5441,6 +5453,10 @@ static void ftrace_update_trampoline(struct ftrace_ops *ops)
arch_ftrace_update_trampoline(ops); arch_ftrace_update_trampoline(ops);
} }
void ftrace_init_trace_array(struct trace_array *tr)
{
INIT_LIST_HEAD(&tr->func_probes);
}
#else #else
static struct ftrace_ops global_ops = { static struct ftrace_ops global_ops = {
...@@ -5495,6 +5511,7 @@ __init void ftrace_init_global_array_ops(struct trace_array *tr) ...@@ -5495,6 +5511,7 @@ __init void ftrace_init_global_array_ops(struct trace_array *tr)
{ {
tr->ops = &global_ops; tr->ops = &global_ops;
tr->ops->private = tr; tr->ops->private = tr;
ftrace_init_trace_array(tr);
} }
void ftrace_init_array_ops(struct trace_array *tr, ftrace_func_t func) void ftrace_init_array_ops(struct trace_array *tr, ftrace_func_t func)
......
...@@ -6815,7 +6815,7 @@ static struct ftrace_probe_ops snapshot_count_probe_ops = { ...@@ -6815,7 +6815,7 @@ static struct ftrace_probe_ops snapshot_count_probe_ops = {
}; };
static int static int
ftrace_trace_snapshot_callback(struct ftrace_hash *hash, ftrace_trace_snapshot_callback(struct trace_array *tr, struct ftrace_hash *hash,
char *glob, char *cmd, char *param, int enable) char *glob, char *cmd, char *param, int enable)
{ {
struct ftrace_probe_ops *ops; struct ftrace_probe_ops *ops;
...@@ -6855,7 +6855,7 @@ ftrace_trace_snapshot_callback(struct ftrace_hash *hash, ...@@ -6855,7 +6855,7 @@ ftrace_trace_snapshot_callback(struct ftrace_hash *hash,
return ret; return ret;
out_reg: out_reg:
ret = register_ftrace_function_probe(glob, ops, count); ret = register_ftrace_function_probe(glob, tr, ops, count);
if (ret >= 0) if (ret >= 0)
alloc_snapshot(&global_trace); alloc_snapshot(&global_trace);
...@@ -7468,6 +7468,8 @@ static int instance_mkdir(const char *name) ...@@ -7468,6 +7468,8 @@ static int instance_mkdir(const char *name)
goto out_free_tr; goto out_free_tr;
} }
ftrace_init_trace_array(tr);
init_tracer_tracefs(tr, tr->dir); init_tracer_tracefs(tr, tr->dir);
init_trace_flags_index(tr); init_trace_flags_index(tr);
__update_tracer_options(tr); __update_tracer_options(tr);
......
...@@ -262,6 +262,9 @@ struct trace_array { ...@@ -262,6 +262,9 @@ struct trace_array {
#ifdef CONFIG_FUNCTION_TRACER #ifdef CONFIG_FUNCTION_TRACER
struct ftrace_ops *ops; struct ftrace_ops *ops;
struct trace_pid_list __rcu *function_pids; struct trace_pid_list __rcu *function_pids;
#ifdef CONFIG_DYNAMIC_FTRACE
struct list_head func_probes;
#endif
/* function tracing enabled */ /* function tracing enabled */
int function_enabled; int function_enabled;
#endif #endif
...@@ -696,6 +699,9 @@ extern void trace_event_follow_fork(struct trace_array *tr, bool enable); ...@@ -696,6 +699,9 @@ extern void trace_event_follow_fork(struct trace_array *tr, bool enable);
#ifdef CONFIG_DYNAMIC_FTRACE #ifdef CONFIG_DYNAMIC_FTRACE
extern unsigned long ftrace_update_tot_cnt; extern unsigned long ftrace_update_tot_cnt;
void ftrace_init_trace_array(struct trace_array *tr);
#else
static inline void ftrace_init_trace_array(struct trace_array *tr) { }
#endif #endif
#define DYN_FTRACE_TEST_NAME trace_selftest_dynamic_test_func #define DYN_FTRACE_TEST_NAME trace_selftest_dynamic_test_func
extern int DYN_FTRACE_TEST_NAME(void); extern int DYN_FTRACE_TEST_NAME(void);
...@@ -883,7 +889,8 @@ extern struct list_head ftrace_pids; ...@@ -883,7 +889,8 @@ extern struct list_head ftrace_pids;
struct ftrace_func_command { struct ftrace_func_command {
struct list_head list; struct list_head list;
char *name; char *name;
int (*func)(struct ftrace_hash *hash, int (*func)(struct trace_array *tr,
struct ftrace_hash *hash,
char *func, char *cmd, char *func, char *cmd,
char *params, int enable); char *params, int enable);
}; };
...@@ -963,8 +970,8 @@ void free_ftrace_func_mapper(struct ftrace_func_mapper *mapper, ...@@ -963,8 +970,8 @@ void free_ftrace_func_mapper(struct ftrace_func_mapper *mapper,
ftrace_mapper_func free_func); ftrace_mapper_func free_func);
extern int extern int
register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, register_ftrace_function_probe(char *glob, struct trace_array *tr,
void *data); struct ftrace_probe_ops *ops, void *data);
extern int extern int
unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops); unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops);
......
...@@ -2611,10 +2611,9 @@ static struct ftrace_probe_ops event_disable_count_probe_ops = { ...@@ -2611,10 +2611,9 @@ static struct ftrace_probe_ops event_disable_count_probe_ops = {
}; };
static int static int
event_enable_func(struct ftrace_hash *hash, event_enable_func(struct trace_array *tr, struct ftrace_hash *hash,
char *glob, char *cmd, char *param, int enabled) char *glob, char *cmd, char *param, int enabled)
{ {
struct trace_array *tr = top_trace_array();
struct trace_event_file *file; struct trace_event_file *file;
struct ftrace_probe_ops *ops; struct ftrace_probe_ops *ops;
struct event_probe_data *data; struct event_probe_data *data;
...@@ -2701,7 +2700,7 @@ event_enable_func(struct ftrace_hash *hash, ...@@ -2701,7 +2700,7 @@ event_enable_func(struct ftrace_hash *hash,
if (ret < 0) if (ret < 0)
goto out_put; goto out_put;
ret = register_ftrace_function_probe(glob, ops, data); ret = register_ftrace_function_probe(glob, tr, ops, data);
/* /*
* The above returns on success the # of functions enabled, * The above returns on success the # of functions enabled,
* but if it didn't find any functions it returns zero. * but if it didn't find any functions it returns zero.
......
...@@ -574,7 +574,8 @@ static struct ftrace_probe_ops stacktrace_probe_ops = { ...@@ -574,7 +574,8 @@ static struct ftrace_probe_ops stacktrace_probe_ops = {
}; };
static int static int
ftrace_trace_probe_callback(struct ftrace_probe_ops *ops, ftrace_trace_probe_callback(struct trace_array *tr,
struct ftrace_probe_ops *ops,
struct ftrace_hash *hash, char *glob, struct ftrace_hash *hash, char *glob,
char *cmd, char *param, int enable) char *cmd, char *param, int enable)
{ {
...@@ -612,13 +613,13 @@ ftrace_trace_probe_callback(struct ftrace_probe_ops *ops, ...@@ -612,13 +613,13 @@ ftrace_trace_probe_callback(struct ftrace_probe_ops *ops,
return ret; return ret;
out_reg: out_reg:
ret = register_ftrace_function_probe(glob, ops, count); ret = register_ftrace_function_probe(glob, tr, ops, count);
return ret < 0 ? ret : 0; return ret < 0 ? ret : 0;
} }
static int static int
ftrace_trace_onoff_callback(struct ftrace_hash *hash, ftrace_trace_onoff_callback(struct trace_array *tr, struct ftrace_hash *hash,
char *glob, char *cmd, char *param, int enable) char *glob, char *cmd, char *param, int enable)
{ {
struct ftrace_probe_ops *ops; struct ftrace_probe_ops *ops;
...@@ -629,24 +630,24 @@ ftrace_trace_onoff_callback(struct ftrace_hash *hash, ...@@ -629,24 +630,24 @@ ftrace_trace_onoff_callback(struct ftrace_hash *hash,
else else
ops = param ? &traceoff_count_probe_ops : &traceoff_probe_ops; ops = param ? &traceoff_count_probe_ops : &traceoff_probe_ops;
return ftrace_trace_probe_callback(ops, hash, glob, cmd, return ftrace_trace_probe_callback(tr, ops, hash, glob, cmd,
param, enable); param, enable);
} }
static int static int
ftrace_stacktrace_callback(struct ftrace_hash *hash, ftrace_stacktrace_callback(struct trace_array *tr, struct ftrace_hash *hash,
char *glob, char *cmd, char *param, int enable) char *glob, char *cmd, char *param, int enable)
{ {
struct ftrace_probe_ops *ops; struct ftrace_probe_ops *ops;
ops = param ? &stacktrace_count_probe_ops : &stacktrace_probe_ops; ops = param ? &stacktrace_count_probe_ops : &stacktrace_probe_ops;
return ftrace_trace_probe_callback(ops, hash, glob, cmd, return ftrace_trace_probe_callback(tr, ops, hash, glob, cmd,
param, enable); param, enable);
} }
static int static int
ftrace_dump_callback(struct ftrace_hash *hash, ftrace_dump_callback(struct trace_array *tr, struct ftrace_hash *hash,
char *glob, char *cmd, char *param, int enable) char *glob, char *cmd, char *param, int enable)
{ {
struct ftrace_probe_ops *ops; struct ftrace_probe_ops *ops;
...@@ -654,12 +655,12 @@ ftrace_dump_callback(struct ftrace_hash *hash, ...@@ -654,12 +655,12 @@ ftrace_dump_callback(struct ftrace_hash *hash,
ops = &dump_probe_ops; ops = &dump_probe_ops;
/* Only dump once. */ /* Only dump once. */
return ftrace_trace_probe_callback(ops, hash, glob, cmd, return ftrace_trace_probe_callback(tr, ops, hash, glob, cmd,
"1", enable); "1", enable);
} }
static int static int
ftrace_cpudump_callback(struct ftrace_hash *hash, ftrace_cpudump_callback(struct trace_array *tr, struct ftrace_hash *hash,
char *glob, char *cmd, char *param, int enable) char *glob, char *cmd, char *param, int enable)
{ {
struct ftrace_probe_ops *ops; struct ftrace_probe_ops *ops;
...@@ -667,7 +668,7 @@ ftrace_cpudump_callback(struct ftrace_hash *hash, ...@@ -667,7 +668,7 @@ ftrace_cpudump_callback(struct ftrace_hash *hash,
ops = &cpudump_probe_ops; ops = &cpudump_probe_ops;
/* Only dump once. */ /* Only dump once. */
return ftrace_trace_probe_callback(ops, hash, glob, cmd, return ftrace_trace_probe_callback(tr, ops, hash, glob, cmd,
"1", enable); "1", enable);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment