Skip to content

Commit 1de7b8b

Browse files
mhiramatacmel
authored andcommitted
perf probe: Search SDT/cached event from all probe caches
Search SDT/cached event from all probe caches if user doesn't pass any binary. With this, we don't have to specify target binary for SDT and named cached events (which start with %). E.g. without this, a target binary must be passed with -x. # perf probe -x /usr/lib64/libc-2.20.so -a %sdt_libc:\* With this change, we don't need it anymore. # perf probe -a %sdt_libc:\* Signed-off-by: Masami Hiramatsu <[email protected]> Cc: Ananth N Mavinakayanahalli <[email protected]> Cc: Brendan Gregg <[email protected]> Cc: Hemant Kumar <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: http://lkml.kernel.org/r/146831792812.17065.2353705982669445313.stgit@devbox Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 42bba26 commit 1de7b8b

File tree

1 file changed

+86
-19
lines changed

1 file changed

+86
-19
lines changed

tools/perf/util/probe-event.c

Lines changed: 86 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2557,41 +2557,60 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,
25572557
return 0;
25582558
}
25592559

2560-
static int __add_probe_trace_events(struct perf_probe_event *pev,
2561-
struct probe_trace_event *tevs,
2562-
int ntevs, bool allow_suffix)
2560+
static int __open_probe_file_and_namelist(bool uprobe,
2561+
struct strlist **namelist)
25632562
{
2564-
int i, fd, ret;
2565-
struct probe_trace_event *tev = NULL;
2566-
struct probe_cache *cache = NULL;
2567-
struct strlist *namelist;
2563+
int fd;
25682564

2569-
fd = probe_file__open(PF_FL_RW | (pev->uprobes ? PF_FL_UPROBE : 0));
2565+
fd = probe_file__open(PF_FL_RW | (uprobe ? PF_FL_UPROBE : 0));
25702566
if (fd < 0)
25712567
return fd;
25722568

25732569
/* Get current event names */
2574-
namelist = probe_file__get_namelist(fd);
2575-
if (!namelist) {
2570+
*namelist = probe_file__get_namelist(fd);
2571+
if (!(*namelist)) {
25762572
pr_debug("Failed to get current event list.\n");
2577-
ret = -ENOMEM;
2578-
goto close_out;
2573+
close(fd);
2574+
return -ENOMEM;
25792575
}
2576+
return fd;
2577+
}
2578+
2579+
static int __add_probe_trace_events(struct perf_probe_event *pev,
2580+
struct probe_trace_event *tevs,
2581+
int ntevs, bool allow_suffix)
2582+
{
2583+
int i, fd[2] = {-1, -1}, up, ret;
2584+
struct probe_trace_event *tev = NULL;
2585+
struct probe_cache *cache = NULL;
2586+
struct strlist *namelist[2] = {NULL, NULL};
2587+
2588+
up = pev->uprobes ? 1 : 0;
2589+
fd[up] = __open_probe_file_and_namelist(up, &namelist[up]);
2590+
if (fd[up] < 0)
2591+
return fd[up];
25802592

25812593
ret = 0;
25822594
for (i = 0; i < ntevs; i++) {
25832595
tev = &tevs[i];
2596+
up = tev->uprobes ? 1 : 0;
2597+
if (fd[up] == -1) { /* Open the kprobe/uprobe_events */
2598+
fd[up] = __open_probe_file_and_namelist(up,
2599+
&namelist[up]);
2600+
if (fd[up] < 0)
2601+
goto close_out;
2602+
}
25842603
/* Skip if the symbol is out of .text or blacklisted */
25852604
if (!tev->point.symbol && !pev->uprobes)
25862605
continue;
25872606

25882607
/* Set new name for tev (and update namelist) */
2589-
ret = probe_trace_event__set_name(tev, pev, namelist,
2608+
ret = probe_trace_event__set_name(tev, pev, namelist[up],
25902609
allow_suffix);
25912610
if (ret < 0)
25922611
break;
25932612

2594-
ret = probe_file__add_event(fd, tev);
2613+
ret = probe_file__add_event(fd[up], tev);
25952614
if (ret < 0)
25962615
break;
25972616

@@ -2614,9 +2633,12 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
26142633
probe_cache__delete(cache);
26152634
}
26162635

2617-
strlist__delete(namelist);
26182636
close_out:
2619-
close(fd);
2637+
for (up = 0; up < 2; up++) {
2638+
strlist__delete(namelist[up]);
2639+
if (fd[up] >= 0)
2640+
close(fd[up]);
2641+
}
26202642
return ret;
26212643
}
26222644

@@ -2989,6 +3011,48 @@ static int find_cached_events(struct perf_probe_event *pev,
29893011
return ret;
29903012
}
29913013

3014+
/* Try to find probe_trace_event from all probe caches */
3015+
static int find_cached_events_all(struct perf_probe_event *pev,
3016+
struct probe_trace_event **tevs)
3017+
{
3018+
struct probe_trace_event *tmp_tevs = NULL;
3019+
struct strlist *bidlist;
3020+
struct str_node *nd;
3021+
char *pathname;
3022+
int ntevs = 0;
3023+
int ret;
3024+
3025+
/* Get the buildid list of all valid caches */
3026+
bidlist = build_id_cache__list_all(true);
3027+
if (!bidlist) {
3028+
ret = -errno;
3029+
pr_debug("Failed to get buildids: %d\n", ret);
3030+
return ret;
3031+
}
3032+
3033+
ret = 0;
3034+
strlist__for_each_entry(nd, bidlist) {
3035+
pathname = build_id_cache__origname(nd->s);
3036+
ret = find_cached_events(pev, &tmp_tevs, pathname);
3037+
/* In the case of cnt == 0, we just skip it */
3038+
if (ret > 0)
3039+
ret = concat_probe_trace_events(tevs, &ntevs,
3040+
&tmp_tevs, ret);
3041+
free(pathname);
3042+
if (ret < 0)
3043+
break;
3044+
}
3045+
strlist__delete(bidlist);
3046+
3047+
if (ret < 0) {
3048+
clear_probe_trace_events(*tevs, ntevs);
3049+
zfree(tevs);
3050+
} else
3051+
ret = ntevs;
3052+
3053+
return ret;
3054+
}
3055+
29923056
static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
29933057
struct probe_trace_event **tevs)
29943058
{
@@ -2998,10 +3062,13 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
29983062
struct str_node *node;
29993063
int ret, i;
30003064

3001-
if (pev->sdt)
3065+
if (pev->sdt) {
30023066
/* For SDT/cached events, we use special search functions */
3003-
return find_cached_events(pev, tevs, pev->target);
3004-
3067+
if (!pev->target)
3068+
return find_cached_events_all(pev, tevs);
3069+
else
3070+
return find_cached_events(pev, tevs, pev->target);
3071+
}
30053072
cache = probe_cache__new(pev->target);
30063073
if (!cache)
30073074
return 0;

0 commit comments

Comments
 (0)