Skip to content

Commit d262271

Browse files
mhiramatrostedt
authored andcommitted
tracing/dynevent: Delegate parsing to create function
Delegate command parsing to each create function so that the command syntax can be customized. This requires changes to the kprobe/uprobe/synthetic event handling, which are also included here. Link: https://lkml.kernel.org/r/e488726f49cbdbc01568618f8680584306c4c79f.1612208610.git.zanussi@kernel.org Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> [ zanussi@kernel.org: added synthetic event modifications ] Signed-off-by: Tom Zanussi <zanussi@kernel.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
1 parent 33b1d14 commit d262271

File tree

9 files changed

+120
-73
lines changed

9 files changed

+120
-73
lines changed

kernel/trace/trace.c

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9412,30 +9412,11 @@ void ftrace_dump(enum ftrace_dump_mode oops_dump_mode)
94129412
}
94139413
EXPORT_SYMBOL_GPL(ftrace_dump);
94149414

9415-
int trace_run_command(const char *buf, int (*createfn)(int, char **))
9416-
{
9417-
char **argv;
9418-
int argc, ret;
9419-
9420-
argc = 0;
9421-
ret = 0;
9422-
argv = argv_split(GFP_KERNEL, buf, &argc);
9423-
if (!argv)
9424-
return -ENOMEM;
9425-
9426-
if (argc)
9427-
ret = createfn(argc, argv);
9428-
9429-
argv_free(argv);
9430-
9431-
return ret;
9432-
}
9433-
94349415
#define WRITE_BUFSIZE 4096
94359416

94369417
ssize_t trace_parse_run_command(struct file *file, const char __user *buffer,
94379418
size_t count, loff_t *ppos,
9438-
int (*createfn)(int, char **))
9419+
int (*createfn)(const char *))
94399420
{
94409421
char *kbuf, *buf, *tmp;
94419422
int ret = 0;
@@ -9483,7 +9464,7 @@ ssize_t trace_parse_run_command(struct file *file, const char __user *buffer,
94839464
if (tmp)
94849465
*tmp = '\0';
94859466

9486-
ret = trace_run_command(buf, createfn);
9467+
ret = createfn(buf);
94879468
if (ret)
94889469
goto out;
94899470
buf += size;

kernel/trace/trace.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,10 +1807,9 @@ extern int tracing_set_cpumask(struct trace_array *tr,
18071807

18081808
#define MAX_EVENT_NAME_LEN 64
18091809

1810-
extern int trace_run_command(const char *buf, int (*createfn)(int, char**));
18111810
extern ssize_t trace_parse_run_command(struct file *file,
18121811
const char __user *buffer, size_t count, loff_t *ppos,
1813-
int (*createfn)(int, char**));
1812+
int (*createfn)(const char *));
18141813

18151814
extern unsigned int err_pos(char *cmd, const char *str);
18161815
extern void tracing_log_err(struct trace_array *tr,

kernel/trace/trace_dynevent.c

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,31 @@ int dyn_event_register(struct dyn_event_operations *ops)
3131
return 0;
3232
}
3333

34-
int dyn_event_release(int argc, char **argv, struct dyn_event_operations *type)
34+
int dyn_event_release(const char *raw_command, struct dyn_event_operations *type)
3535
{
3636
struct dyn_event *pos, *n;
3737
char *system = NULL, *event, *p;
38-
int ret = -ENOENT;
38+
int argc, ret = -ENOENT;
39+
char **argv;
40+
41+
argv = argv_split(GFP_KERNEL, raw_command, &argc);
42+
if (!argv)
43+
return -ENOMEM;
3944

4045
if (argv[0][0] == '-') {
41-
if (argv[0][1] != ':')
42-
return -EINVAL;
46+
if (argv[0][1] != ':') {
47+
ret = -EINVAL;
48+
goto out;
49+
}
4350
event = &argv[0][2];
4451
} else {
4552
event = strchr(argv[0], ':');
46-
if (!event)
47-
return -EINVAL;
53+
if (!event) {
54+
ret = -EINVAL;
55+
goto out;
56+
}
4857
event++;
4958
}
50-
argc--; argv++;
5159

5260
p = strchr(event, '/');
5361
if (p) {
@@ -63,29 +71,30 @@ int dyn_event_release(int argc, char **argv, struct dyn_event_operations *type)
6371
if (type && type != pos->ops)
6472
continue;
6573
if (!pos->ops->match(system, event,
66-
argc, (const char **)argv, pos))
74+
argc - 1, (const char **)argv + 1, pos))
6775
continue;
6876

6977
ret = pos->ops->free(pos);
7078
if (ret)
7179
break;
7280
}
7381
mutex_unlock(&event_mutex);
74-
82+
out:
83+
argv_free(argv);
7584
return ret;
7685
}
7786

78-
static int create_dyn_event(int argc, char **argv)
87+
static int create_dyn_event(const char *raw_command)
7988
{
8089
struct dyn_event_operations *ops;
8190
int ret = -ENODEV;
8291

83-
if (argv[0][0] == '-' || argv[0][0] == '!')
84-
return dyn_event_release(argc, argv, NULL);
92+
if (raw_command[0] == '-' || raw_command[0] == '!')
93+
return dyn_event_release(raw_command, NULL);
8594

8695
mutex_lock(&dyn_event_ops_mutex);
8796
list_for_each_entry(ops, &dyn_event_ops_list, list) {
88-
ret = ops->create(argc, (const char **)argv);
97+
ret = ops->create(raw_command);
8998
if (!ret || ret != -ECANCELED)
9099
break;
91100
}

kernel/trace/trace_dynevent.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ struct dyn_event;
3939
*/
4040
struct dyn_event_operations {
4141
struct list_head list;
42-
int (*create)(int argc, const char *argv[]);
42+
int (*create)(const char *raw_command);
4343
int (*show)(struct seq_file *m, struct dyn_event *ev);
4444
bool (*is_busy)(struct dyn_event *ev);
4545
int (*free)(struct dyn_event *ev);
@@ -97,7 +97,7 @@ void *dyn_event_seq_start(struct seq_file *m, loff_t *pos);
9797
void *dyn_event_seq_next(struct seq_file *m, void *v, loff_t *pos);
9898
void dyn_event_seq_stop(struct seq_file *m, void *v);
9999
int dyn_events_release_all(struct dyn_event_operations *type);
100-
int dyn_event_release(int argc, char **argv, struct dyn_event_operations *type);
100+
int dyn_event_release(const char *raw_command, struct dyn_event_operations *type);
101101

102102
/*
103103
* for_each_dyn_event - iterate over the dyn_event list

kernel/trace/trace_events_synth.c

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ static void synth_err(u8 err_type, u8 err_pos)
6262
err_type, err_pos);
6363
}
6464

65-
static int create_synth_event(int argc, const char **argv);
65+
static int create_synth_event(const char *raw_command);
6666
static int synth_event_show(struct seq_file *m, struct dyn_event *ev);
6767
static int synth_event_release(struct dyn_event *ev);
6868
static bool synth_event_is_busy(struct dyn_event *ev);
@@ -1383,18 +1383,30 @@ int synth_event_delete(const char *event_name)
13831383
}
13841384
EXPORT_SYMBOL_GPL(synth_event_delete);
13851385

1386-
static int create_or_delete_synth_event(int argc, char **argv)
1386+
static int create_or_delete_synth_event(const char *raw_command)
13871387
{
1388-
const char *name = argv[0];
1389-
int ret;
1388+
char **argv, *name = NULL;
1389+
int argc = 0, ret = 0;
1390+
1391+
argv = argv_split(GFP_KERNEL, raw_command, &argc);
1392+
if (!argv)
1393+
return -ENOMEM;
1394+
1395+
if (!argc)
1396+
goto free;
1397+
1398+
name = argv[0];
13901399

13911400
/* trace_run_command() ensures argc != 0 */
13921401
if (name[0] == '!') {
13931402
ret = synth_event_delete(name + 1);
1394-
return ret;
1403+
goto free;
13951404
}
13961405

13971406
ret = __create_synth_event(argc - 1, name, (const char **)argv + 1);
1407+
free:
1408+
argv_free(argv);
1409+
13981410
return ret == -ECANCELED ? -EINVAL : ret;
13991411
}
14001412

@@ -1403,7 +1415,7 @@ static int synth_event_run_command(struct dynevent_cmd *cmd)
14031415
struct synth_event *se;
14041416
int ret;
14051417

1406-
ret = trace_run_command(cmd->seq.buffer, create_or_delete_synth_event);
1418+
ret = create_or_delete_synth_event(cmd->seq.buffer);
14071419
if (ret)
14081420
return ret;
14091421

@@ -1939,23 +1951,43 @@ int synth_event_trace_end(struct synth_event_trace_state *trace_state)
19391951
}
19401952
EXPORT_SYMBOL_GPL(synth_event_trace_end);
19411953

1942-
static int create_synth_event(int argc, const char **argv)
1954+
static int create_synth_event(const char *raw_command)
19431955
{
1944-
const char *name = argv[0];
1945-
int len;
1956+
char **argv, *name;
1957+
int len, argc = 0, ret = 0;
1958+
1959+
argv = argv_split(GFP_KERNEL, raw_command, &argc);
1960+
if (!argv) {
1961+
ret = -ENOMEM;
1962+
return ret;
1963+
}
19461964

1947-
if (name[0] != 's' || name[1] != ':')
1948-
return -ECANCELED;
1965+
if (!argc)
1966+
goto free;
1967+
1968+
name = argv[0];
1969+
1970+
if (name[0] != 's' || name[1] != ':') {
1971+
ret = -ECANCELED;
1972+
goto free;
1973+
}
19491974
name += 2;
19501975

19511976
/* This interface accepts group name prefix */
19521977
if (strchr(name, '/')) {
19531978
len = str_has_prefix(name, SYNTH_SYSTEM "/");
1954-
if (len == 0)
1955-
return -EINVAL;
1979+
if (len == 0) {
1980+
ret = -EINVAL;
1981+
goto free;
1982+
}
19561983
name += len;
19571984
}
1958-
return __create_synth_event(argc - 1, name, argv + 1);
1985+
1986+
ret = __create_synth_event(argc - 1, name, (const char **)argv + 1);
1987+
free:
1988+
argv_free(argv);
1989+
1990+
return ret;
19591991
}
19601992

19611993
static int synth_event_release(struct dyn_event *ev)

kernel/trace/trace_kprobe.c

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ static int __init set_kprobe_boot_events(char *str)
3535
}
3636
__setup("kprobe_event=", set_kprobe_boot_events);
3737

38-
static int trace_kprobe_create(int argc, const char **argv);
38+
static int trace_kprobe_create(const char *raw_command);
3939
static int trace_kprobe_show(struct seq_file *m, struct dyn_event *ev);
4040
static int trace_kprobe_release(struct dyn_event *ev);
4141
static bool trace_kprobe_is_busy(struct dyn_event *ev);
@@ -711,7 +711,7 @@ static inline void sanitize_event_name(char *name)
711711
*name = '_';
712712
}
713713

714-
static int trace_kprobe_create(int argc, const char *argv[])
714+
static int __trace_kprobe_create(int argc, const char *argv[])
715715
{
716716
/*
717717
* Argument syntax:
@@ -910,20 +910,25 @@ static int trace_kprobe_create(int argc, const char *argv[])
910910
goto out;
911911
}
912912

913-
static int create_or_delete_trace_kprobe(int argc, char **argv)
913+
static int trace_kprobe_create(const char *raw_command)
914+
{
915+
return trace_probe_create(raw_command, __trace_kprobe_create);
916+
}
917+
918+
static int create_or_delete_trace_kprobe(const char *raw_command)
914919
{
915920
int ret;
916921

917-
if (argv[0][0] == '-')
918-
return dyn_event_release(argc, argv, &trace_kprobe_ops);
922+
if (raw_command[0] == '-')
923+
return dyn_event_release(raw_command, &trace_kprobe_ops);
919924

920-
ret = trace_kprobe_create(argc, (const char **)argv);
925+
ret = trace_kprobe_create(raw_command);
921926
return ret == -ECANCELED ? -EINVAL : ret;
922927
}
923928

924929
static int trace_kprobe_run_command(struct dynevent_cmd *cmd)
925930
{
926-
return trace_run_command(cmd->seq.buffer, create_or_delete_trace_kprobe);
931+
return create_or_delete_trace_kprobe(cmd->seq.buffer);
927932
}
928933

929934
/**
@@ -1084,7 +1089,7 @@ int kprobe_event_delete(const char *name)
10841089

10851090
snprintf(buf, MAX_EVENT_NAME_LEN, "-:%s", name);
10861091

1087-
return trace_run_command(buf, create_or_delete_trace_kprobe);
1092+
return create_or_delete_trace_kprobe(buf);
10881093
}
10891094
EXPORT_SYMBOL_GPL(kprobe_event_delete);
10901095

@@ -1886,7 +1891,7 @@ static __init void setup_boot_kprobe_events(void)
18861891
if (p)
18871892
*p++ = '\0';
18881893

1889-
ret = trace_run_command(cmd, create_or_delete_trace_kprobe);
1894+
ret = create_or_delete_trace_kprobe(cmd);
18901895
if (ret)
18911896
pr_warn("Failed to add event(%d): %s\n", ret, cmd);
18921897

@@ -1980,8 +1985,7 @@ static __init int kprobe_trace_self_tests_init(void)
19801985

19811986
pr_info("Testing kprobe tracing: ");
19821987

1983-
ret = trace_run_command("p:testprobe kprobe_trace_selftest_target $stack $stack0 +0($stack)",
1984-
create_or_delete_trace_kprobe);
1988+
ret = create_or_delete_trace_kprobe("p:testprobe kprobe_trace_selftest_target $stack $stack0 +0($stack)");
19851989
if (WARN_ON_ONCE(ret)) {
19861990
pr_warn("error on probing function entry.\n");
19871991
warn++;
@@ -2002,8 +2006,7 @@ static __init int kprobe_trace_self_tests_init(void)
20022006
}
20032007
}
20042008

2005-
ret = trace_run_command("r:testprobe2 kprobe_trace_selftest_target $retval",
2006-
create_or_delete_trace_kprobe);
2009+
ret = create_or_delete_trace_kprobe("r:testprobe2 kprobe_trace_selftest_target $retval");
20072010
if (WARN_ON_ONCE(ret)) {
20082011
pr_warn("error on probing function return.\n");
20092012
warn++;
@@ -2076,13 +2079,13 @@ static __init int kprobe_trace_self_tests_init(void)
20762079
trace_probe_event_call(&tk->tp), file);
20772080
}
20782081

2079-
ret = trace_run_command("-:testprobe", create_or_delete_trace_kprobe);
2082+
ret = create_or_delete_trace_kprobe("-:testprobe");
20802083
if (WARN_ON_ONCE(ret)) {
20812084
pr_warn("error on deleting a probe.\n");
20822085
warn++;
20832086
}
20842087

2085-
ret = trace_run_command("-:testprobe2", create_or_delete_trace_kprobe);
2088+
ret = create_or_delete_trace_kprobe("-:testprobe2");
20862089
if (WARN_ON_ONCE(ret)) {
20872090
pr_warn("error on deleting a probe.\n");
20882091
warn++;

kernel/trace/trace_probe.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,3 +1134,20 @@ bool trace_probe_match_command_args(struct trace_probe *tp,
11341134
}
11351135
return true;
11361136
}
1137+
1138+
int trace_probe_create(const char *raw_command, int (*createfn)(int, const char **))
1139+
{
1140+
int argc = 0, ret = 0;
1141+
char **argv;
1142+
1143+
argv = argv_split(GFP_KERNEL, raw_command, &argc);
1144+
if (!argv)
1145+
return -ENOMEM;
1146+
1147+
if (argc)
1148+
ret = createfn(argc, (const char **)argv);
1149+
1150+
argv_free(argv);
1151+
1152+
return ret;
1153+
}

kernel/trace/trace_probe.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ struct event_file_link *trace_probe_get_file_link(struct trace_probe *tp,
341341
int trace_probe_compare_arg_type(struct trace_probe *a, struct trace_probe *b);
342342
bool trace_probe_match_command_args(struct trace_probe *tp,
343343
int argc, const char **argv);
344+
int trace_probe_create(const char *raw_command, int (*createfn)(int, const char **));
344345

345346
#define trace_probe_for_each_link(pos, tp) \
346347
list_for_each_entry(pos, &(tp)->event->files, list)

0 commit comments

Comments
 (0)