aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@kernel.org>2016-07-12 06:05:28 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-07-13 22:09:07 -0400
commit1de7b8bf728fd8d51b0cc644003d0694c6e0feef (patch)
tree785a66caa4604d1c2e3b9761a29c43f35a56a65c
parent42bba263eb58800b6239a0cb35ac17fd29379277 (diff)
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 <mhiramat@kernel.org> Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com> Cc: Brendan Gregg <brendan.d.gregg@gmail.com> Cc: Hemant Kumar <hemant@linux.vnet.ibm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/146831792812.17065.2353705982669445313.stgit@devbox Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/probe-event.c105
1 files changed, 86 insertions, 19 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 7b96e687568e..c63e3b8704fe 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2557,41 +2557,60 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,
2557 return 0; 2557 return 0;
2558} 2558}
2559 2559
2560static int __add_probe_trace_events(struct perf_probe_event *pev, 2560static int __open_probe_file_and_namelist(bool uprobe,
2561 struct probe_trace_event *tevs, 2561 struct strlist **namelist)
2562 int ntevs, bool allow_suffix)
2563{ 2562{
2564 int i, fd, ret; 2563 int fd;
2565 struct probe_trace_event *tev = NULL;
2566 struct probe_cache *cache = NULL;
2567 struct strlist *namelist;
2568 2564
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));
2570 if (fd < 0) 2566 if (fd < 0)
2571 return fd; 2567 return fd;
2572 2568
2573 /* Get current event names */ 2569 /* Get current event names */
2574 namelist = probe_file__get_namelist(fd); 2570 *namelist = probe_file__get_namelist(fd);
2575 if (!namelist) { 2571 if (!(*namelist)) {
2576 pr_debug("Failed to get current event list.\n"); 2572 pr_debug("Failed to get current event list.\n");
2577 ret = -ENOMEM; 2573 close(fd);
2578 goto close_out; 2574 return -ENOMEM;
2579 } 2575 }
2576 return fd;
2577}
2578
2579static 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];
2580 2592
2581 ret = 0; 2593 ret = 0;
2582 for (i = 0; i < ntevs; i++) { 2594 for (i = 0; i < ntevs; i++) {
2583 tev = &tevs[i]; 2595 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 }
2584 /* Skip if the symbol is out of .text or blacklisted */ 2603 /* Skip if the symbol is out of .text or blacklisted */
2585 if (!tev->point.symbol && !pev->uprobes) 2604 if (!tev->point.symbol && !pev->uprobes)
2586 continue; 2605 continue;
2587 2606
2588 /* Set new name for tev (and update namelist) */ 2607 /* 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],
2590 allow_suffix); 2609 allow_suffix);
2591 if (ret < 0) 2610 if (ret < 0)
2592 break; 2611 break;
2593 2612
2594 ret = probe_file__add_event(fd, tev); 2613 ret = probe_file__add_event(fd[up], tev);
2595 if (ret < 0) 2614 if (ret < 0)
2596 break; 2615 break;
2597 2616
@@ -2614,9 +2633,12 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
2614 probe_cache__delete(cache); 2633 probe_cache__delete(cache);
2615 } 2634 }
2616 2635
2617 strlist__delete(namelist);
2618close_out: 2636close_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 }
2620 return ret; 2642 return ret;
2621} 2643}
2622 2644
@@ -2989,6 +3011,48 @@ static int find_cached_events(struct perf_probe_event *pev,
2989 return ret; 3011 return ret;
2990} 3012}
2991 3013
3014/* Try to find probe_trace_event from all probe caches */
3015static 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
2992static int find_probe_trace_events_from_cache(struct perf_probe_event *pev, 3056static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
2993 struct probe_trace_event **tevs) 3057 struct probe_trace_event **tevs)
2994{ 3058{
@@ -2998,10 +3062,13 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
2998 struct str_node *node; 3062 struct str_node *node;
2999 int ret, i; 3063 int ret, i;
3000 3064
3001 if (pev->sdt) 3065 if (pev->sdt) {
3002 /* For SDT/cached events, we use special search functions */ 3066 /* For SDT/cached events, we use special search functions */
3003 return find_cached_events(pev, tevs, pev->target); 3067 if (!pev->target)
3004 3068 return find_cached_events_all(pev, tevs);
3069 else
3070 return find_cached_events(pev, tevs, pev->target);
3071 }
3005 cache = probe_cache__new(pev->target); 3072 cache = probe_cache__new(pev->target);
3006 if (!cache) 3073 if (!cache)
3007 return 0; 3074 return 0;