Commit 12fae5ef authored by Wang Nan's avatar Wang Nan Committed by Arnaldo Carvalho de Melo

perf probe: Link trace_probe_event into perf_probe_event

This patch drops struct __event_package structure.  Instead, it adds a
'struct trace_probe_event' pointer to 'struct perf_probe_event'.

The trace_probe_event information gives further patches a chance to
access actual probe points and actual arguments.

Using them, 'perf probe' can get the whole list of added probes and
print them at once.

Other users like the upcoming bpf_loader will be able to attach one bpf
program to different probing points of an inline function (which has
multiple probing points) and glob functions.

Moreover, by reading the arguments information, bpf code for reading
those arguments can be generated.
Signed-off-by: default avatarWang Nan <wangnan0@huawei.com>
Acked-by: default avatarMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1441368963-11565-2-git-send-email-namhyung@kernel.org
[namhyung: extract necessary part from the existing patch]
Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 844dffa5
...@@ -2759,59 +2759,39 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev, ...@@ -2759,59 +2759,39 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
return find_probe_trace_events_from_map(pev, tevs); return find_probe_trace_events_from_map(pev, tevs);
} }
struct __event_package { int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs)
struct perf_probe_event *pev;
struct probe_trace_event *tevs;
int ntevs;
};
static int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs,
struct __event_package **ppkgs)
{ {
int i, ret; int i, ret;
struct __event_package *pkgs;
ret = 0;
pkgs = zalloc(sizeof(struct __event_package) * npevs);
if (pkgs == NULL)
return -ENOMEM;
ret = init_symbol_maps(pevs->uprobes); ret = init_symbol_maps(pevs->uprobes);
if (ret < 0) { if (ret < 0)
free(pkgs);
return ret; return ret;
}
/* Loop 1: convert all events */ /* Loop 1: convert all events */
for (i = 0; i < npevs; i++) { for (i = 0; i < npevs; i++) {
pkgs[i].pev = &pevs[i];
/* Init kprobe blacklist if needed */ /* Init kprobe blacklist if needed */
if (!pkgs[i].pev->uprobes) if (!pevs[i].uprobes)
kprobe_blacklist__init(); kprobe_blacklist__init();
/* Convert with or without debuginfo */ /* Convert with or without debuginfo */
ret = convert_to_probe_trace_events(pkgs[i].pev, ret = convert_to_probe_trace_events(&pevs[i], &pevs[i].tevs);
&pkgs[i].tevs);
if (ret < 0) if (ret < 0)
return ret; return ret;
pkgs[i].ntevs = ret; pevs[i].ntevs = ret;
} }
/* This just release blacklist only if allocated */ /* This just release blacklist only if allocated */
kprobe_blacklist__release(); kprobe_blacklist__release();
*ppkgs = pkgs;
return 0; return 0;
} }
static int apply_perf_probe_events(struct __event_package *pkgs, int npevs) int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs)
{ {
int i, ret = 0; int i, ret = 0;
/* Loop 2: add all events */ /* Loop 2: add all events */
for (i = 0; i < npevs; i++) { for (i = 0; i < npevs; i++) {
ret = __add_probe_trace_events(pkgs[i].pev, pkgs[i].tevs, ret = __add_probe_trace_events(&pevs[i], pevs[i].tevs,
pkgs[i].ntevs, pevs[i].ntevs,
probe_conf.force_add); probe_conf.force_add);
if (ret < 0) if (ret < 0)
break; break;
...@@ -2819,33 +2799,30 @@ static int apply_perf_probe_events(struct __event_package *pkgs, int npevs) ...@@ -2819,33 +2799,30 @@ static int apply_perf_probe_events(struct __event_package *pkgs, int npevs)
return ret; return ret;
} }
static void cleanup_perf_probe_events(struct __event_package *pkgs, int npevs) void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs)
{ {
int i, j; int i, j;
if (pkgs == NULL)
return;
/* Loop 3: cleanup and free trace events */ /* Loop 3: cleanup and free trace events */
for (i = 0; i < npevs; i++) { for (i = 0; i < npevs; i++) {
for (j = 0; j < pkgs[i].ntevs; j++) for (j = 0; j < pevs[i].ntevs; j++)
clear_probe_trace_event(&pkgs[i].tevs[j]); clear_probe_trace_event(&pevs[i].tevs[j]);
zfree(&pkgs[i].tevs); zfree(&pevs[i].tevs);
pevs[i].ntevs = 0;
} }
free(pkgs);
exit_symbol_maps(); exit_symbol_maps();
} }
int add_perf_probe_events(struct perf_probe_event *pevs, int npevs) int add_perf_probe_events(struct perf_probe_event *pevs, int npevs)
{ {
int ret; int ret;
struct __event_package *pkgs = NULL;
ret = convert_perf_probe_events(pevs, npevs, &pkgs); ret = convert_perf_probe_events(pevs, npevs);
if (ret == 0) if (ret == 0)
ret = apply_perf_probe_events(pkgs, npevs); ret = apply_perf_probe_events(pevs, npevs);
cleanup_perf_probe_events(pkgs, npevs); cleanup_perf_probe_events(pevs, npevs);
return ret; return ret;
} }
......
...@@ -87,6 +87,8 @@ struct perf_probe_event { ...@@ -87,6 +87,8 @@ struct perf_probe_event {
bool uprobes; /* Uprobe event flag */ bool uprobes; /* Uprobe event flag */
char *target; /* Target binary */ char *target; /* Target binary */
struct perf_probe_arg *args; /* Arguments */ struct perf_probe_arg *args; /* Arguments */
struct probe_trace_event *tevs;
int ntevs;
}; };
/* Line range */ /* Line range */
...@@ -138,6 +140,9 @@ extern void line_range__clear(struct line_range *lr); ...@@ -138,6 +140,9 @@ extern void line_range__clear(struct line_range *lr);
extern int line_range__init(struct line_range *lr); extern int line_range__init(struct line_range *lr);
extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs); extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs);
extern int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs);
extern int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs);
extern void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs);
extern int del_perf_probe_events(struct strfilter *filter); extern int del_perf_probe_events(struct strfilter *filter);
extern int show_perf_probe_events(struct strfilter *filter); extern int show_perf_probe_events(struct strfilter *filter);
extern int show_line_range(struct line_range *lr, const char *module, extern int show_line_range(struct line_range *lr, const char *module,
......
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