mirror of https://gitee.com/openkylin/linux.git
perf probe: Add --bootconfig to output definition in bootconfig format
Now the boot-time tracing supports kprobes events and that must be written in bootconfig file in the following format. ftrace.event.kprobes.<EVENT_NAME>.probes = <PROBE-DEF> 'perf probe' already supports --definition (-D) action to show probe definitions, but the format is for tracefs: [p|r][:EVENT_NAME] <PROBE-DEF> This patch adds the --bootconfig option for -D action so that it outputs the probe definitions in bootconfig format. E.g. $ perf probe --bootconfig -D "path_lookupat:7 err:s32 s:string" ftrace.event.kprobes.path_lookupat_L7.probe = 'path_lookupat.isra.0+309 err_s32=%ax:s32 s_string=+0(%r13):string' Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lore.kernel.org/lkml/162282412351.452340.14871995440005640114.stgit@devnote2 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
d26ea48144
commit
45237f9898
|
@ -347,7 +347,10 @@ static int perf_add_probe_events(struct perf_probe_event *pevs, int npevs)
|
||||||
goto out_cleanup;
|
goto out_cleanup;
|
||||||
|
|
||||||
if (params.command == 'D') { /* it shows definition */
|
if (params.command == 'D') { /* it shows definition */
|
||||||
ret = show_probe_trace_events(pevs, npevs);
|
if (probe_conf.bootconfig)
|
||||||
|
ret = show_bootconfig_events(pevs, npevs);
|
||||||
|
else
|
||||||
|
ret = show_probe_trace_events(pevs, npevs);
|
||||||
goto out_cleanup;
|
goto out_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,6 +584,8 @@ __cmd_probe(int argc, const char **argv)
|
||||||
"Look for files with symbols relative to this directory"),
|
"Look for files with symbols relative to this directory"),
|
||||||
OPT_CALLBACK(0, "target-ns", NULL, "pid",
|
OPT_CALLBACK(0, "target-ns", NULL, "pid",
|
||||||
"target pid for namespace contexts", opt_set_target_ns),
|
"target pid for namespace contexts", opt_set_target_ns),
|
||||||
|
OPT_BOOLEAN(0, "bootconfig", &probe_conf.bootconfig,
|
||||||
|
"Output probe definition with bootconfig format"),
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -692,6 +697,11 @@ __cmd_probe(int argc, const char **argv)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
|
if (probe_conf.bootconfig && params.uprobes) {
|
||||||
|
pr_err(" Error: --bootconfig doesn't support uprobes.\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
__fallthrough;
|
||||||
case 'a':
|
case 'a':
|
||||||
|
|
||||||
/* Ensure the last given target is used */
|
/* Ensure the last given target is used */
|
||||||
|
|
|
@ -3564,6 +3564,78 @@ int show_probe_trace_events(struct perf_probe_event *pevs, int npevs)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int show_bootconfig_event(struct probe_trace_event *tev)
|
||||||
|
{
|
||||||
|
struct probe_trace_point *tp = &tev->point;
|
||||||
|
struct strbuf buf;
|
||||||
|
char *ret = NULL;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (strbuf_init(&buf, 32) < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
err = synthesize_kprobe_trace_def(tp, &buf);
|
||||||
|
if (err >= 0)
|
||||||
|
err = synthesize_probe_trace_args(tev, &buf);
|
||||||
|
if (err >= 0)
|
||||||
|
ret = strbuf_detach(&buf, NULL);
|
||||||
|
strbuf_release(&buf);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
printf("'%s'", ret);
|
||||||
|
free(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int show_bootconfig_events(struct perf_probe_event *pevs, int npevs)
|
||||||
|
{
|
||||||
|
struct strlist *namelist = strlist__new(NULL, NULL);
|
||||||
|
struct probe_trace_event *tev;
|
||||||
|
struct perf_probe_event *pev;
|
||||||
|
char *cur_name = NULL;
|
||||||
|
int i, j, ret = 0;
|
||||||
|
|
||||||
|
if (!namelist)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
for (j = 0; j < npevs && !ret; j++) {
|
||||||
|
pev = &pevs[j];
|
||||||
|
if (pev->group && strcmp(pev->group, "probe"))
|
||||||
|
pr_warning("WARN: Group name %s is ignored\n", pev->group);
|
||||||
|
if (pev->uprobes) {
|
||||||
|
pr_warning("ERROR: Bootconfig doesn't support uprobes\n");
|
||||||
|
ret = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (i = 0; i < pev->ntevs && !ret; i++) {
|
||||||
|
tev = &pev->tevs[i];
|
||||||
|
/* Skip if the symbol is out of .text or blacklisted */
|
||||||
|
if (!tev->point.symbol && !pev->uprobes)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Set new name for tev (and update namelist) */
|
||||||
|
ret = probe_trace_event__set_name(tev, pev,
|
||||||
|
namelist, true);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!cur_name || strcmp(cur_name, tev->event)) {
|
||||||
|
printf("%sftrace.event.kprobes.%s.probe = ",
|
||||||
|
cur_name ? "\n" : "", tev->event);
|
||||||
|
cur_name = tev->event;
|
||||||
|
} else
|
||||||
|
printf(", ");
|
||||||
|
ret = show_bootconfig_event(tev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
strlist__delete(namelist);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs)
|
int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs)
|
||||||
{
|
{
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
|
@ -15,6 +15,7 @@ struct probe_conf {
|
||||||
bool force_add;
|
bool force_add;
|
||||||
bool no_inlines;
|
bool no_inlines;
|
||||||
bool cache;
|
bool cache;
|
||||||
|
bool bootconfig;
|
||||||
int max_probes;
|
int max_probes;
|
||||||
unsigned long magic_num;
|
unsigned long magic_num;
|
||||||
};
|
};
|
||||||
|
@ -163,6 +164,7 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs);
|
||||||
int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs);
|
int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs);
|
||||||
int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs);
|
int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs);
|
||||||
int show_probe_trace_events(struct perf_probe_event *pevs, int npevs);
|
int show_probe_trace_events(struct perf_probe_event *pevs, int npevs);
|
||||||
|
int show_bootconfig_events(struct perf_probe_event *pevs, int npevs);
|
||||||
void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs);
|
void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs);
|
||||||
|
|
||||||
struct strfilter;
|
struct strfilter;
|
||||||
|
|
Loading…
Reference in New Issue