Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf list: Show SDT and pre-cached events

Show SDT and pre-cached events by perf-list with "sdt". This also shows
the binary and build-id where the events are placed only when there are
same name events on different binaries.

e.g.:

# perf list sdt

List of pre-defined events (to be used in -e):

sdt_libc:lll_futex_wake [SDT event]
sdt_libc:lll_lock_wait_private [SDT event]
sdt_libc:longjmp [SDT event]
sdt_libc:longjmp_target [SDT event]
...
sdt_libstdcxx:rethrow@/usr/bin/gcc(0cc207fc4b27) [SDT event]
sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
sdt_libstdcxx:throw@/usr/bin/gcc(0cc207fc4b27) [SDT event]
sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)

The binary path and build-id are shown in below format;

<GROUP>:<EVENT>@<PATH>(<BUILD-ID>)

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
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/20160624090646.25421.44225.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Masami Hiramatsu and committed by
Arnaldo Carvalho de Melo
40218dae 1de7b8bf

+98 -1
+5 -1
tools/perf/builtin-list.c
··· 25 25 OPT_END() 26 26 }; 27 27 const char * const list_usage[] = { 28 - "perf list [hw|sw|cache|tracepoint|pmu|event_glob]", 28 + "perf list [hw|sw|cache|tracepoint|pmu|sdt|event_glob]", 29 29 NULL 30 30 }; 31 31 ··· 62 62 print_hwcache_events(NULL, raw_dump); 63 63 else if (strcmp(argv[i], "pmu") == 0) 64 64 print_pmu_events(NULL, raw_dump); 65 + else if (strcmp(argv[i], "sdt") == 0) 66 + print_sdt_events(NULL, NULL, raw_dump); 65 67 else if ((sep = strchr(argv[i], ':')) != NULL) { 66 68 int sep_idx; 67 69 ··· 78 76 79 77 s[sep_idx] = '\0'; 80 78 print_tracepoint_events(s, s + sep_idx + 1, raw_dump); 79 + print_sdt_events(s, s + sep_idx + 1, raw_dump); 81 80 free(s); 82 81 } else { 83 82 if (asprintf(&s, "*%s*", argv[i]) < 0) { ··· 92 89 print_hwcache_events(s, raw_dump); 93 90 print_pmu_events(s, raw_dump); 94 91 print_tracepoint_events(NULL, s, raw_dump); 92 + print_sdt_events(NULL, s, raw_dump); 95 93 free(s); 96 94 } 97 95 }
+82
tools/perf/util/parse-events.c
··· 20 20 #include "pmu.h" 21 21 #include "thread_map.h" 22 22 #include "cpumap.h" 23 + #include "probe-file.h" 23 24 #include "asm/bug.h" 24 25 25 26 #define MAX_NAME_LEN 100 ··· 1985 1984 return ret; 1986 1985 } 1987 1986 1987 + void print_sdt_events(const char *subsys_glob, const char *event_glob, 1988 + bool name_only) 1989 + { 1990 + struct probe_cache *pcache; 1991 + struct probe_cache_entry *ent; 1992 + struct strlist *bidlist, *sdtlist; 1993 + struct strlist_config cfg = {.dont_dupstr = true}; 1994 + struct str_node *nd, *nd2; 1995 + char *buf, *path, *ptr = NULL; 1996 + bool show_detail = false; 1997 + int ret; 1998 + 1999 + sdtlist = strlist__new(NULL, &cfg); 2000 + if (!sdtlist) { 2001 + pr_debug("Failed to allocate new strlist for SDT\n"); 2002 + return; 2003 + } 2004 + bidlist = build_id_cache__list_all(true); 2005 + if (!bidlist) { 2006 + pr_debug("Failed to get buildids: %d\n", errno); 2007 + return; 2008 + } 2009 + strlist__for_each_entry(nd, bidlist) { 2010 + pcache = probe_cache__new(nd->s); 2011 + if (!pcache) 2012 + continue; 2013 + list_for_each_entry(ent, &pcache->entries, node) { 2014 + if (!ent->sdt) 2015 + continue; 2016 + if (subsys_glob && 2017 + !strglobmatch(ent->pev.group, subsys_glob)) 2018 + continue; 2019 + if (event_glob && 2020 + !strglobmatch(ent->pev.event, event_glob)) 2021 + continue; 2022 + ret = asprintf(&buf, "%s:%s@%s", ent->pev.group, 2023 + ent->pev.event, nd->s); 2024 + if (ret > 0) 2025 + strlist__add(sdtlist, buf); 2026 + } 2027 + probe_cache__delete(pcache); 2028 + } 2029 + strlist__delete(bidlist); 2030 + 2031 + strlist__for_each_entry(nd, sdtlist) { 2032 + buf = strchr(nd->s, '@'); 2033 + if (buf) 2034 + *(buf++) = '\0'; 2035 + if (name_only) { 2036 + printf("%s ", nd->s); 2037 + continue; 2038 + } 2039 + nd2 = strlist__next(nd); 2040 + if (nd2) { 2041 + ptr = strchr(nd2->s, '@'); 2042 + if (ptr) 2043 + *ptr = '\0'; 2044 + if (strcmp(nd->s, nd2->s) == 0) 2045 + show_detail = true; 2046 + } 2047 + if (show_detail) { 2048 + path = build_id_cache__origname(buf); 2049 + ret = asprintf(&buf, "%s@%s(%.12s)", nd->s, path, buf); 2050 + if (ret > 0) { 2051 + printf(" %-50s [%s]\n", buf, "SDT event"); 2052 + free(buf); 2053 + } 2054 + } else 2055 + printf(" %-50s [%s]\n", nd->s, "SDT event"); 2056 + if (nd2) { 2057 + if (strcmp(nd->s, nd2->s) != 0) 2058 + show_detail = false; 2059 + if (ptr) 2060 + *ptr = '@'; 2061 + } 2062 + } 2063 + strlist__delete(sdtlist); 2064 + } 2065 + 1988 2066 int print_hwcache_events(const char *event_glob, bool name_only) 1989 2067 { 1990 2068 unsigned int type, op, i, evt_i = 0, evt_num = 0; ··· 2246 2166 } 2247 2167 2248 2168 print_tracepoint_events(NULL, NULL, name_only); 2169 + 2170 + print_sdt_events(NULL, NULL, name_only); 2249 2171 } 2250 2172 2251 2173 int parse_events__is_hardcoded_term(struct parse_events_term *term)
+2
tools/perf/util/parse-events.h
··· 183 183 void print_tracepoint_events(const char *subsys_glob, const char *event_glob, 184 184 bool name_only); 185 185 int print_hwcache_events(const char *event_glob, bool name_only); 186 + void print_sdt_events(const char *subsys_glob, const char *event_glob, 187 + bool name_only); 186 188 int is_valid_tracepoint(const char *event_string); 187 189 188 190 int valid_event_mount(const char *eventfs);
+9
tools/perf/util/probe-file.h
··· 24 24 #define for_each_probe_cache_entry(entry, pcache) \ 25 25 list_for_each_entry(entry, &pcache->entries, node) 26 26 27 + /* probe-file.c depends on libelf */ 28 + #ifdef HAVE_LIBELF_SUPPORT 27 29 int probe_file__open(int flag); 28 30 int probe_file__open_both(int *kfd, int *ufd, int flag); 29 31 struct strlist *probe_file__get_namelist(int fd); ··· 54 52 struct probe_cache_entry *probe_cache__find_by_name(struct probe_cache *pcache, 55 53 const char *group, const char *event); 56 54 int probe_cache__show_all_caches(struct strfilter *filter); 55 + #else /* ! HAVE_LIBELF_SUPPORT */ 56 + static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused) 57 + { 58 + return NULL; 59 + } 60 + #define probe_cache__delete(pcache) do {} while (0) 61 + #endif 57 62 #endif