Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1389465 > unrolled thread
| Started by | Masami Hiramatsu <mhiramat@kernel.org> |
|---|---|
| First post | 2016-04-27 20:40 +0200 |
| Last post | 2016-04-29 16:00 +0200 |
| Articles | 8 on this page of 28 — 4 participants |
Back to article view | Back to linux.kernel
[PATCH perf/core v5 00/15] perf-probe --cache and SDT support Masami Hiramatsu <mhiramat@kernel.org> - 2016-04-27 20:40 +0200
[PATCH perf/core v5 07/15] perf probe: Remove caches when --cache is given Masami Hiramatsu <mhiramat@kernel.org> - 2016-04-27 20:40 +0200
[PATCH perf/core v5 03/15] perf-buildid-cache: Use lsdir for looking up buildid caches Masami Hiramatsu <mhiramat@kernel.org> - 2016-04-27 20:40 +0200
[PATCH perf/core v5 15/15] perf probe: Support @BUILDID or @FILE suffix for SDT events Masami Hiramatsu <mhiramat@kernel.org> - 2016-04-27 20:40 +0200
[PATCH perf/core v5 13/15] perf-list: Skip SDTs placed in invalid binaries Masami Hiramatsu <mhiramat@kernel.org> - 2016-04-27 20:40 +0200
[PATCH perf/core v5 02/15] perf-buildid-cache: Use path/to/bin/buildid/elf instead of path/to/bin/buildid Masami Hiramatsu <mhiramat@kernel.org> - 2016-04-27 20:40 +0200
Re: [PATCH perf/core v5 02/15] perf-buildid-cache: Use path/to/bin/buildid/elf instead of path/to/bin/buildid Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-04-27 23:20 +0200
Re: [PATCH perf/core v5 02/15] perf-buildid-cache: Use path/to/bin/buildid/elf instead of path/to/bin/buildid Masami Hiramatsu <mhiramat@kernel.org> - 2016-04-28 04:00 +0200
Re: [PATCH perf/core v5 02/15] perf-buildid-cache: Use path/to/bin/buildid/elf instead of path/to/bin/buildid Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-04-27 23:30 +0200
Re: [PATCH perf/core v5 02/15] perf-buildid-cache: Use path/to/bin/buildid/elf instead of path/to/bin/buildid Masami Hiramatsu <mhiramat@kernel.org> - 2016-04-28 04:00 +0200
Re: [PATCH perf/core v5 02/15] perf-buildid-cache: Use path/to/bin/buildid/elf instead of path/to/bin/buildid Namhyung Kim <namhyung@kernel.org> - 2016-04-28 03:30 +0200
Re: [PATCH perf/core v5 02/15] perf-buildid-cache: Use path/to/bin/buildid/elf instead of path/to/bin/buildid Masami Hiramatsu <mhiramat@kernel.org> - 2016-04-29 01:00 +0200
[PATCH perf/core v5 04/15] perf probe: Add --cache option to cache the probe definitions Masami Hiramatsu <mhiramat@kernel.org> - 2016-04-27 20:40 +0200
Re: [PATCH perf/core v5 04/15] perf probe: Add --cache option to cache the probe definitions Namhyung Kim <namhyung@kernel.org> - 2016-04-28 04:20 +0200
Re: [PATCH perf/core v5 04/15] perf probe: Add --cache option to cache the probe definitions Masami Hiramatsu <mhiramat@kernel.org> - 2016-04-29 01:20 +0200
Re: [PATCH perf/core v5 04/15] perf probe: Add --cache option to cache the probe definitions Namhyung Kim <namhyung@kernel.org> - 2016-04-28 04:40 +0200
Re: [PATCH perf/core v5 04/15] perf probe: Add --cache option to cache the probe definitions Masami Hiramatsu <mhiramat@kernel.org> - 2016-04-29 01:10 +0200
[PATCH perf/core v5 14/15] perf probe: Allow wildcard for cached events Masami Hiramatsu <mhiramat@kernel.org> - 2016-04-27 20:40 +0200
Re: [PATCH perf/core v5 14/15] perf probe: Allow wildcard for cached events Masami Hiramatsu <mhiramat@kernel.org> - 2016-04-27 20:50 +0200
[PATCH perf/core v5.1 14/15] perf probe: Allow wildcard for cached events Masami Hiramatsu <mhiramat@kernel.org> - 2016-04-27 21:20 +0200
Re: [PATCH perf/core v5.1 14/15] perf probe: Allow wildcard for cached events Hemant Kumar <hemant@linux.vnet.ibm.com> - 2016-04-27 22:40 +0200
[PATCH perf/core v5 12/15] perf-list: Show SDT and pre-cached events Masami Hiramatsu <mhiramat@kernel.org> - 2016-04-27 20:40 +0200
Re: [PATCH perf/core v5 12/15] perf-list: Show SDT and pre-cached events Hemant Kumar <hemant@linux.vnet.ibm.com> - 2016-04-27 22:50 +0200
[PATCH perf/core v5 11/15] perf probe: Accept %sdt and %cached event name Masami Hiramatsu <mhiramat@kernel.org> - 2016-04-27 20:40 +0200
Re: [PATCH perf/core v5 11/15] perf probe: Accept %sdt and %cached event name Namhyung Kim <namhyung@kernel.org> - 2016-04-28 07:30 +0200
Re: [PATCH perf/core v5 11/15] perf probe: Accept %sdt and %cached event name Masami Hiramatsu <mhiramat@kernel.org> - 2016-04-29 02:20 +0200
[PATCH perf/core v5 09/15] perf probe: Add group name support Masami Hiramatsu <mhiramat@kernel.org> - 2016-04-27 20:40 +0200
Re: [PATCH perf/core v5 00/15] perf-probe --cache and SDT support Hemant Kumar <hemant@linux.vnet.ibm.com> - 2016-04-29 16:00 +0200
Page 2 of 2 — ← Prev page 1 [2]
| From | Hemant Kumar <hemant@linux.vnet.ibm.com> |
|---|---|
| Date | 2016-04-27 22:40 +0200 |
| Subject | Re: [PATCH perf/core v5.1 14/15] perf probe: Allow wildcard for cached events |
| Message-ID | <rsEpA-7BA-9@gated-at.bofh.it> |
| In reply to | #1389511 |
On 04/28/2016 12:45 AM, Masami Hiramatsu wrote:
> Allo glob wildcard for reusing cached/SDT events. This also
> automatically find the target binaries, e.g.
>
> # perf probe -a %sdt_libc:\*
>
> This example adds probes for all SDT in libc.
> Note that the SDTs must have been scanned by perf buildid-cache.
>
> Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> ---
> Changes in v5.1:
> - Fix a SEGV bug when a group name is omitted. (Thanks Hemant!)
Thanks for the fix.
Acked-by: Hemant Kumar <hemant@linux.vnet.ibm.com>
> ---
> tools/perf/util/probe-event.c | 153 ++++++++++++++++++++++++++++++++++++++++-
> tools/perf/util/probe-event.h | 1
> tools/perf/util/probe-file.c | 33 ++++++++-
> tools/perf/util/probe-file.h | 5 +
> 4 files changed, 183 insertions(+), 9 deletions(-)
>
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index 1a9ea2b..11752d2 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -236,7 +236,7 @@ static void clear_perf_probe_point(struct perf_probe_point *pp)
> free(pp->lazy_line);
> }
>
> -static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
> +void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
> {
> int i;
>
> @@ -1206,7 +1206,7 @@ static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev)
> ptr = strchr(*arg, ':');
> if (ptr) {
> *ptr = '\0';
> - if (!is_c_func_name(*arg))
> + if (!pev->sdt && !is_c_func_name(*arg))
> goto ng_name;
> pev->group = strdup(*arg);
> if (!pev->group)
> @@ -1214,7 +1214,7 @@ static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev)
> *arg = ptr + 1;
> } else
> pev->group = NULL;
> - if (!is_c_func_name(*arg)) {
> + if (!pev->sdt && !is_c_func_name(*arg)) {
> ng_name:
> semantic_error("%s is bad for event name -it must "
> "follow C symbol-naming rule.\n", *arg);
> @@ -1640,6 +1640,11 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev)
> p = strchr(argv[1], ':');
> if (p) {
> tp->module = strndup(argv[1], p - argv[1]);
> + if (!tp->module) {
> + ret = -ENOMEM;
> + goto out;
> + }
> + tev->uprobes = (tp->module[0] == '/');
> p++;
> } else
> p = argv[1];
> @@ -2485,7 +2490,7 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,
> int ret;
>
> /* If probe_event or trace_event already have the name, reuse it */
> - if (pev->event)
> + if (pev->event && !pev->sdt)
> event = pev->event;
> else if (tev->event)
> event = tev->event;
> @@ -2498,7 +2503,7 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,
> else
> event = tev->point.realname;
> }
> - if (pev->group)
> + if (pev->group && !pev->sdt)
> group = pev->group;
> else if (tev->group)
> group = tev->group;
> @@ -2860,6 +2865,137 @@ errout:
>
> bool __weak arch__prefers_symtab(void) { return false; }
>
> +/* Concatinate two arrays */
> +static void *memcat(void *a, size_t sz_a, void *b, size_t sz_b)
> +{
> + void *ret;
> +
> + ret = malloc(sz_a + sz_b);
> + if (ret) {
> + memcpy(ret, a, sz_a);
> + memcpy(ret + sz_a, b, sz_b);
> + }
> + return ret;
> +}
> +
> +static int
> +concat_probe_trace_events(struct probe_trace_event **tevs, int *ntevs,
> + struct probe_trace_event **tevs2, int ntevs2)
> +{
> + struct probe_trace_event *new_tevs;
> + int ret = 0;
> +
> + if (ntevs == 0) {
> + *tevs = *tevs2;
> + *ntevs = ntevs2;
> + *tevs2 = NULL;
> + return 0;
> + }
> +
> + if (*ntevs + ntevs2 > probe_conf.max_probes)
> + ret = -E2BIG;
> + else {
> + /* Concatinate the array of probe_trace_event */
> + new_tevs = memcat(*tevs, (*ntevs) * sizeof(**tevs),
> + *tevs2, ntevs2 * sizeof(**tevs2));
> + if (!new_tevs)
> + ret = -ENOMEM;
> + else {
> + free(*tevs);
> + *tevs = new_tevs;
> + *ntevs += ntevs2;
> + }
> + }
> + if (ret < 0)
> + clear_probe_trace_events(*tevs2, ntevs2);
> + zfree(tevs2);
> +
> + return ret;
> +}
> +
> +/* Try to find probe_trace_event from given probe caches */
> +static int find_cached_events(struct perf_probe_event *pev,
> + struct probe_trace_event **tevs,
> + const char *target)
> +{
> + struct probe_cache *cache;
> + struct probe_cache_entry *entry;
> + struct probe_trace_event *tmp_tevs = NULL;
> + int ntevs = 0;
> + int ret = 0;
> +
> + cache = probe_cache__new(target);
> + if (!cache)
> + return -ENOENT;
> +
> + for_each_probe_cache_entry(entry, cache) {
> + /* Skip the cache entry which has no name */
> + if (!entry->pev.event || !entry->pev.group)
> + continue;
> + if ((!pev->group || strglobmatch(entry->pev.group, pev->group)) &&
> + strglobmatch(entry->pev.event, pev->event)) {
> + ret = probe_cache_entry__get_event(entry, &tmp_tevs);
> + if (ret > 0)
> + ret = concat_probe_trace_events(tevs, &ntevs,
> + &tmp_tevs, ret);
> + if (ret < 0)
> + break;
> + }
> + }
> + probe_cache__delete(cache);
> + if (ret < 0) {
> + clear_probe_trace_events(*tevs, ntevs);
> + zfree(tevs);
> + } else {
> + ret = ntevs;
> + if (target[0] == '/')
> + pev->uprobes = true;
> + }
> +
> + return ret;
> +}
> +
> +/* Try to find probe_trace_event from all probe caches */
> +static int find_cached_events_all(struct perf_probe_event *pev,
> + struct probe_trace_event **tevs)
> +{
> + struct probe_trace_event *tmp_tevs = NULL;
> + struct strlist *bidlist;
> + struct str_node *nd;
> + char *pathname;
> + int ntevs = 0;
> + int ret;
> +
> + /* Get the buildid list of all valid caches */
> + ret = build_id_cache__list_all(&bidlist, true);
> + if (ret < 0) {
> + pr_debug("Failed to get buildids: %d\n", ret);
> + return ret;
> + }
> +
> + ret = 0;
> + strlist__for_each(nd, bidlist) {
> + pathname = build_id_cache__origname(nd->s);
> + ret = find_cached_events(pev, &tmp_tevs, pathname);
> + if (ret > 0)
> + ret = concat_probe_trace_events(tevs, &ntevs,
> + &tmp_tevs, ret);
> + /* In the case of cnt == 0, we just skip it */
> + free(pathname);
> + if (ret < 0)
> + break;
> + }
> + strlist__delete(bidlist);
> +
> + if (ret < 0) {
> + clear_probe_trace_events(*tevs, ntevs);
> + zfree(tevs);
> + } else
> + ret = ntevs;
> +
> + return ret;
> +}
> +
> static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
> struct probe_trace_event **tevs)
> {
> @@ -2869,6 +3005,13 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
> struct str_node *node;
> int ret, i;
>
> + if (pev->sdt) {
> + /* For SDT/cached events, we use special search functions */
> + if (!pev->target)
> + return find_cached_events_all(pev, tevs);
> + else
> + return find_cached_events(pev, tevs, pev->target);
> + }
> cache = probe_cache__new(pev->target);
> if (!cache)
> return 0;
> diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
> index 2a23efe..39b5a35 100644
> --- a/tools/perf/util/probe-event.h
> +++ b/tools/perf/util/probe-event.h
> @@ -134,6 +134,7 @@ bool perf_probe_event_need_dwarf(struct perf_probe_event *pev);
> /* Release event contents */
> void clear_perf_probe_event(struct perf_probe_event *pev);
> void clear_probe_trace_event(struct probe_trace_event *tev);
> +void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs);
>
> /* Command string to line-range */
> int parse_line_range_desc(const char *cmd, struct line_range *lr);
> diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
> index 2437b48..896d645 100644
> --- a/tools/perf/util/probe-file.c
> +++ b/tools/perf/util/probe-file.c
> @@ -360,6 +360,31 @@ probe_cache_entry__new(struct perf_probe_event *pev)
> return ret;
> }
>
> +int probe_cache_entry__get_event(struct probe_cache_entry *entry,
> + struct probe_trace_event **tevs)
> +{
> + struct probe_trace_event *tev;
> + struct str_node *node;
> + int ret, i;
> +
> + ret = strlist__nr_entries(entry->tevlist);
> + if (ret > probe_conf.max_probes)
> + return -E2BIG;
> +
> + *tevs = zalloc(ret * sizeof(*tev));
> + if (!*tevs)
> + return -ENOMEM;
> +
> + i = 0;
> + strlist__for_each(node, entry->tevlist) {
> + tev = &(*tevs)[i++];
> + ret = parse_probe_trace_command(node->s, tev);
> + if (ret < 0)
> + break;
> + }
> + return i;
> +}
> +
> /* For the kernel probe caches, pass target = NULL */
> static int probe_cache__open(struct probe_cache *pcache, const char *target)
> {
> @@ -528,7 +553,7 @@ probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)
> if (!cmd)
> return NULL;
>
> - list_for_each_entry(entry, &pcache->list, list) {
> + for_each_probe_cache_entry(entry, pcache) {
> if (pev->sdt) {
> if (entry->pev.event &&
> streql(entry->pev.event, pev->event) &&
> @@ -558,7 +583,7 @@ probe_cache__find_by_name(struct probe_cache *pcache,
> {
> struct probe_cache_entry *entry = NULL;
>
> - list_for_each_entry(entry, &pcache->list, list) {
> + for_each_probe_cache_entry(entry, pcache) {
> /* Hit if same event name or same command-string */
> if (streql(entry->pev.group, group) &&
> streql(entry->pev.event, event))
> @@ -711,7 +736,7 @@ int probe_cache__commit(struct probe_cache *pcache)
> if (ret < 0)
> goto out;
>
> - list_for_each_entry(entry, &pcache->list, list) {
> + for_each_probe_cache_entry(entry, pcache) {
> ret = probe_cache_entry__write(entry, pcache->fd);
> pr_debug("Cache committed: %d\n", ret);
> if (ret < 0)
> @@ -750,7 +775,7 @@ static int probe_cache__show_entries(struct probe_cache *pcache,
> {
> struct probe_cache_entry *entry;
>
> - list_for_each_entry(entry, &pcache->list, list) {
> + for_each_probe_cache_entry(entry, pcache) {
> if (probe_cache_entry__compare(entry, filter))
> printf("%s\n", entry->spev);
> }
> diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
> index ce98162..0faf083 100644
> --- a/tools/perf/util/probe-file.h
> +++ b/tools/perf/util/probe-file.h
> @@ -21,6 +21,8 @@ struct probe_cache {
>
> #define PF_FL_UPROBE 1
> #define PF_FL_RW 2
> +#define for_each_probe_cache_entry(entry, pcache) \
> + list_for_each_entry(entry, &pcache->list, list)
>
> /* probe-file.c depends on libelf */
> #ifdef HAVE_LIBELF_SUPPORT
> @@ -34,6 +36,9 @@ int probe_file__get_events(int fd, struct strfilter *filter,
> struct strlist *plist);
> int probe_file__del_strlist(int fd, struct strlist *namelist);
>
> +int probe_cache_entry__get_event(struct probe_cache_entry *entry,
> + struct probe_trace_event **tevs);
> +
> struct probe_cache *probe_cache__new(const char *target);
> int probe_cache__add_entry(struct probe_cache *pcache,
> struct perf_probe_event *pev,
>
--
Thanks,
Hemant Kumar
[toc] | [prev] | [next] | [standalone]
| From | Masami Hiramatsu <mhiramat@kernel.org> |
|---|---|
| Date | 2016-04-27 20:40 +0200 |
| Subject | [PATCH perf/core v5 12/15] perf-list: Show SDT and pre-cached events |
| Message-ID | <rsCxt-5Ye-55@gated-at.bofh.it> |
| In reply to | #1389465 |
From: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
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 <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
Changes in v5:
- Fix a build error for minimal option.
Changes in v4:
- Update patch description.
- Change event list format.
---
tools/perf/builtin-list.c | 4 ++
tools/perf/util/parse-events.c | 83 ++++++++++++++++++++++++++++++++++++++++
tools/perf/util/parse-events.h | 2 +
tools/perf/util/probe-file.h | 9 ++++
4 files changed, 98 insertions(+)
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index 5e22db4..3cba865 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -62,6 +62,8 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
print_hwcache_events(NULL, raw_dump);
else if (strcmp(argv[i], "pmu") == 0)
print_pmu_events(NULL, raw_dump);
+ else if (strcmp(argv[i], "sdt") == 0)
+ print_sdt_events(NULL, NULL, raw_dump);
else if ((sep = strchr(argv[i], ':')) != NULL) {
int sep_idx;
@@ -76,6 +78,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
s[sep_idx] = '\0';
print_tracepoint_events(s, s + sep_idx + 1, raw_dump);
+ print_sdt_events(s, s + sep_idx + 1, raw_dump);
free(s);
} else {
if (asprintf(&s, "*%s*", argv[i]) < 0) {
@@ -89,6 +92,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
print_hwcache_events(s, raw_dump);
print_pmu_events(s, raw_dump);
print_tracepoint_events(NULL, s, raw_dump);
+ print_sdt_events(NULL, s, raw_dump);
free(s);
}
}
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index bcbc983..f9c8b7b 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -20,6 +20,7 @@
#include "pmu.h"
#include "thread_map.h"
#include "cpumap.h"
+#include "probe-file.h"
#include "asm/bug.h"
#define MAX_NAME_LEN 100
@@ -1976,6 +1977,86 @@ static bool is_event_supported(u8 type, unsigned config)
return ret;
}
+void print_sdt_events(const char *subsys_glob, const char *event_glob,
+ bool name_only)
+{
+ struct probe_cache *pcache;
+ struct probe_cache_entry *ent;
+ struct strlist *bidlist, *sdtlist;
+ struct strlist_config cfg = {.dont_dupstr = true};
+ struct str_node *nd, *nd2;
+ char *buf, *path, *ptr = NULL;
+ bool show_detail = false;
+ int ret;
+
+ sdtlist = strlist__new(NULL, &cfg);
+ if (!sdtlist) {
+ pr_debug("Failed to allocate new strlist for SDT\n");
+ return;
+ }
+ ret = build_id_cache__list_all(&bidlist);
+ if (ret < 0) {
+ pr_debug("Failed to get buildids: %d\n", ret);
+ return;
+ }
+ strlist__for_each(nd, bidlist) {
+ pcache = probe_cache__new(nd->s);
+ if (!pcache)
+ continue;
+ if (!list_empty(&pcache->list))
+ list_for_each_entry(ent, &pcache->list, list) {
+ if (!ent->sdt)
+ continue;
+ if (subsys_glob &&
+ !strglobmatch(ent->pev.group, subsys_glob))
+ continue;
+ if (event_glob &&
+ !strglobmatch(ent->pev.event, event_glob))
+ continue;
+ ret = asprintf(&buf, "%s:%s@%s", ent->pev.group,
+ ent->pev.event, nd->s);
+ if (ret > 0)
+ strlist__add(sdtlist, buf);
+ }
+ probe_cache__delete(pcache);
+ }
+ strlist__delete(bidlist);
+
+ strlist__for_each(nd, sdtlist) {
+ buf = strchr(nd->s, '@');
+ if (buf)
+ *(buf++) = '\0';
+ if (name_only) {
+ printf("%s ", nd->s);
+ continue;
+ }
+ nd2 = strlist__next(nd);
+ if (nd2) {
+ ptr = strchr(nd2->s, '@');
+ if (ptr)
+ *ptr = '\0';
+ if (strcmp(nd->s, nd2->s) == 0)
+ show_detail = true;
+ }
+ if (show_detail) {
+ path = build_id_cache__origname(buf);
+ ret = asprintf(&buf, "%s@%s(%.12s)", nd->s, path, buf);
+ if (ret > 0) {
+ printf(" %-50s [%s]\n", buf, "SDT event");
+ free(buf);
+ }
+ } else
+ printf(" %-50s [%s]\n", nd->s, "SDT event");
+ if (nd2) {
+ if (strcmp(nd->s, nd2->s) != 0)
+ show_detail = false;
+ if (ptr)
+ *ptr = '@';
+ }
+ }
+ strlist__delete(sdtlist);
+}
+
int print_hwcache_events(const char *event_glob, bool name_only)
{
unsigned int type, op, i, evt_i = 0, evt_num = 0;
@@ -2158,6 +2239,8 @@ void print_events(const char *event_glob, bool name_only)
}
print_tracepoint_events(NULL, NULL, name_only);
+
+ print_sdt_events(NULL, NULL, name_only);
}
int parse_events__is_hardcoded_term(struct parse_events_term *term)
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index d740c3c..c08daa9 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -182,6 +182,8 @@ void print_symbol_events(const char *event_glob, unsigned type,
void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
bool name_only);
int print_hwcache_events(const char *event_glob, bool name_only);
+void print_sdt_events(const char *subsys_glob, const char *event_glob,
+ bool name_only);
int is_valid_tracepoint(const char *event_string);
int valid_event_mount(const char *eventfs);
diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
index 93aa193..ce98162 100644
--- a/tools/perf/util/probe-file.h
+++ b/tools/perf/util/probe-file.h
@@ -22,6 +22,8 @@ struct probe_cache {
#define PF_FL_UPROBE 1
#define PF_FL_RW 2
+/* probe-file.c depends on libelf */
+#ifdef HAVE_LIBELF_SUPPORT
int probe_file__open(int flag);
int probe_file__open_both(int *kfd, int *ufd, int flag);
struct strlist *probe_file__get_namelist(int fd);
@@ -46,4 +48,11 @@ struct probe_cache_entry *probe_cache__find(struct probe_cache *pcache,
struct probe_cache_entry *probe_cache__find_by_name(struct probe_cache *pcache,
const char *group, const char *event);
int probe_cache__show_all_caches(struct strfilter *filter);
+#else /* ! HAVE_LIBELF_SUPPORT */
+static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused)
+{
+ return NULL;
+}
+#define probe_cache__delete(pcache) do {} while(0)
+#endif
#endif
[toc] | [prev] | [next] | [standalone]
| From | Hemant Kumar <hemant@linux.vnet.ibm.com> |
|---|---|
| Date | 2016-04-27 22:50 +0200 |
| Subject | Re: [PATCH perf/core v5 12/15] perf-list: Show SDT and pre-cached events |
| Message-ID | <rsEzf-7F4-7@gated-at.bofh.it> |
| In reply to | #1389476 |
On 04/28/2016 12:08 AM, Masami Hiramatsu wrote:
> From: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
>
> 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 <masami.hiramatsu.pt@hitachi.com>
> Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Acked-by: Hemant Kumar <hemant@linux.vnet.ibm.com>
> ---
> Changes in v5:
> - Fix a build error for minimal option.
>
> Changes in v4:
> - Update patch description.
> - Change event list format.
> ---
> tools/perf/builtin-list.c | 4 ++
> tools/perf/util/parse-events.c | 83 ++++++++++++++++++++++++++++++++++++++++
> tools/perf/util/parse-events.h | 2 +
> tools/perf/util/probe-file.h | 9 ++++
> 4 files changed, 98 insertions(+)
>
> diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
> index 5e22db4..3cba865 100644
> --- a/tools/perf/builtin-list.c
> +++ b/tools/perf/builtin-list.c
> @@ -62,6 +62,8 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
> print_hwcache_events(NULL, raw_dump);
> else if (strcmp(argv[i], "pmu") == 0)
> print_pmu_events(NULL, raw_dump);
> + else if (strcmp(argv[i], "sdt") == 0)
> + print_sdt_events(NULL, NULL, raw_dump);
> else if ((sep = strchr(argv[i], ':')) != NULL) {
> int sep_idx;
>
> @@ -76,6 +78,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
>
> s[sep_idx] = '\0';
> print_tracepoint_events(s, s + sep_idx + 1, raw_dump);
> + print_sdt_events(s, s + sep_idx + 1, raw_dump);
> free(s);
> } else {
> if (asprintf(&s, "*%s*", argv[i]) < 0) {
> @@ -89,6 +92,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
> print_hwcache_events(s, raw_dump);
> print_pmu_events(s, raw_dump);
> print_tracepoint_events(NULL, s, raw_dump);
> + print_sdt_events(NULL, s, raw_dump);
> free(s);
> }
> }
> diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
> index bcbc983..f9c8b7b 100644
> --- a/tools/perf/util/parse-events.c
> +++ b/tools/perf/util/parse-events.c
> @@ -20,6 +20,7 @@
> #include "pmu.h"
> #include "thread_map.h"
> #include "cpumap.h"
> +#include "probe-file.h"
> #include "asm/bug.h"
>
> #define MAX_NAME_LEN 100
> @@ -1976,6 +1977,86 @@ static bool is_event_supported(u8 type, unsigned config)
> return ret;
> }
>
> +void print_sdt_events(const char *subsys_glob, const char *event_glob,
> + bool name_only)
> +{
> + struct probe_cache *pcache;
> + struct probe_cache_entry *ent;
> + struct strlist *bidlist, *sdtlist;
> + struct strlist_config cfg = {.dont_dupstr = true};
> + struct str_node *nd, *nd2;
> + char *buf, *path, *ptr = NULL;
> + bool show_detail = false;
> + int ret;
> +
> + sdtlist = strlist__new(NULL, &cfg);
> + if (!sdtlist) {
> + pr_debug("Failed to allocate new strlist for SDT\n");
> + return;
> + }
> + ret = build_id_cache__list_all(&bidlist);
> + if (ret < 0) {
> + pr_debug("Failed to get buildids: %d\n", ret);
> + return;
> + }
> + strlist__for_each(nd, bidlist) {
> + pcache = probe_cache__new(nd->s);
> + if (!pcache)
> + continue;
> + if (!list_empty(&pcache->list))
> + list_for_each_entry(ent, &pcache->list, list) {
> + if (!ent->sdt)
> + continue;
> + if (subsys_glob &&
> + !strglobmatch(ent->pev.group, subsys_glob))
> + continue;
> + if (event_glob &&
> + !strglobmatch(ent->pev.event, event_glob))
> + continue;
> + ret = asprintf(&buf, "%s:%s@%s", ent->pev.group,
> + ent->pev.event, nd->s);
> + if (ret > 0)
> + strlist__add(sdtlist, buf);
> + }
> + probe_cache__delete(pcache);
> + }
> + strlist__delete(bidlist);
> +
> + strlist__for_each(nd, sdtlist) {
> + buf = strchr(nd->s, '@');
> + if (buf)
> + *(buf++) = '\0';
> + if (name_only) {
> + printf("%s ", nd->s);
> + continue;
> + }
> + nd2 = strlist__next(nd);
> + if (nd2) {
> + ptr = strchr(nd2->s, '@');
> + if (ptr)
> + *ptr = '\0';
> + if (strcmp(nd->s, nd2->s) == 0)
> + show_detail = true;
> + }
> + if (show_detail) {
> + path = build_id_cache__origname(buf);
> + ret = asprintf(&buf, "%s@%s(%.12s)", nd->s, path, buf);
> + if (ret > 0) {
> + printf(" %-50s [%s]\n", buf, "SDT event");
> + free(buf);
> + }
> + } else
> + printf(" %-50s [%s]\n", nd->s, "SDT event");
> + if (nd2) {
> + if (strcmp(nd->s, nd2->s) != 0)
> + show_detail = false;
> + if (ptr)
> + *ptr = '@';
> + }
> + }
> + strlist__delete(sdtlist);
> +}
> +
> int print_hwcache_events(const char *event_glob, bool name_only)
> {
> unsigned int type, op, i, evt_i = 0, evt_num = 0;
> @@ -2158,6 +2239,8 @@ void print_events(const char *event_glob, bool name_only)
> }
>
> print_tracepoint_events(NULL, NULL, name_only);
> +
> + print_sdt_events(NULL, NULL, name_only);
> }
>
> int parse_events__is_hardcoded_term(struct parse_events_term *term)
> diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
> index d740c3c..c08daa9 100644
> --- a/tools/perf/util/parse-events.h
> +++ b/tools/perf/util/parse-events.h
> @@ -182,6 +182,8 @@ void print_symbol_events(const char *event_glob, unsigned type,
> void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
> bool name_only);
> int print_hwcache_events(const char *event_glob, bool name_only);
> +void print_sdt_events(const char *subsys_glob, const char *event_glob,
> + bool name_only);
> int is_valid_tracepoint(const char *event_string);
>
> int valid_event_mount(const char *eventfs);
> diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
> index 93aa193..ce98162 100644
> --- a/tools/perf/util/probe-file.h
> +++ b/tools/perf/util/probe-file.h
> @@ -22,6 +22,8 @@ struct probe_cache {
> #define PF_FL_UPROBE 1
> #define PF_FL_RW 2
>
> +/* probe-file.c depends on libelf */
> +#ifdef HAVE_LIBELF_SUPPORT
> int probe_file__open(int flag);
> int probe_file__open_both(int *kfd, int *ufd, int flag);
> struct strlist *probe_file__get_namelist(int fd);
> @@ -46,4 +48,11 @@ struct probe_cache_entry *probe_cache__find(struct probe_cache *pcache,
> struct probe_cache_entry *probe_cache__find_by_name(struct probe_cache *pcache,
> const char *group, const char *event);
> int probe_cache__show_all_caches(struct strfilter *filter);
> +#else /* ! HAVE_LIBELF_SUPPORT */
> +static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused)
> +{
> + return NULL;
> +}
> +#define probe_cache__delete(pcache) do {} while(0)
> +#endif
> #endif
>
--
Thanks,
Hemant Kumar
[toc] | [prev] | [next] | [standalone]
| From | Masami Hiramatsu <mhiramat@kernel.org> |
|---|---|
| Date | 2016-04-27 20:40 +0200 |
| Subject | [PATCH perf/core v5 11/15] perf probe: Accept %sdt and %cached event name |
| Message-ID | <rsCxu-5Ye-63@gated-at.bofh.it> |
| In reply to | #1389465 |
From: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
To improbe usability, support %[PROVIDER:]SDTEVENT format to
add new probes on SDT and cached events.
e.g.
----
# perf probe -x /lib/libc-2.17.so %lll_lock_wait_private
Added new event:
sdt_libc:lll_lock_wait_private (on %lll_lock_wait_private in
/usr/lib/libc-2.17.so)
You can now use it in all perf tools, such as:
perf record -e sdt_libc:lll_lock_wait_private -aR sleep 1
# perf probe -l | more
sdt_libc:lll_lock_wait_private (on __lll_lock_wait_private+21
in /usr/lib/libc-2.17.so)
----
Note that this is not only for SDT events, but also normal
events with event-name.
e.g. define "myevent" on cache (-n doesn't add the real probe)
----
# perf probe -x ./perf --cache -n --add 'myevent=dso__load $params'
----
Reuse the "myevent" from cache as below.
----
# perf probe -x ./perf %myevent
----
TODO:
Wildcard is not supported yet.
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
---
tools/perf/Documentation/perf-probe.txt | 3 +
tools/perf/util/probe-event.c | 78 ++++++++++++++++++++++---------
tools/perf/util/probe-event.h | 1
tools/perf/util/probe-file.c | 9 ++++
4 files changed, 69 insertions(+), 22 deletions(-)
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 7a258e9..43523be 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -151,6 +151,8 @@ Probe points are defined by following syntax.
3) Define event based on source file with lazy pattern
[[GROUP:]EVENT=]SRC;PTN [ARG ...]
+ 4) Pre-defined SDT events
+ %[PROVIDER:]SDTEVENT
'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. You can also specify a group name by 'GROUP', if omitted, set 'probe' is used for kprobe and 'probe_<bin>' is used for uprobe.
Note that using existing group name can conflict with other events. Especially, using the group name reserved for kernel modules can hide embedded events in the
@@ -158,6 +160,7 @@ modules.
'FUNC' specifies a probed function name, and it may have one of the following options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is the relative-line number from function entry line, and '%return' means that it probes function return. And ';PTN' means lazy matching pattern (see LAZY MATCHING). Note that ';PTN' must be the end of the probe point definition. In addition, '@SRC' specifies a source file which has that function.
It is also possible to specify a probe point by the source line number or lazy matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file path, ':ALN' is the line number and ';PTN' is the lazy matching pattern.
'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT).
+'SDTEVENT' and 'PROVIDER' is the pre-defined event name which is defined by user SDT (Statically Defined Tracing) or the pre-cached probes with event name.
PROBE ARGUMENT
--------------
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index b2c6a4a..1a9ea2b 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1199,6 +1199,34 @@ err:
return err;
}
+static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev)
+{
+ char *ptr;
+
+ ptr = strchr(*arg, ':');
+ if (ptr) {
+ *ptr = '\0';
+ if (!is_c_func_name(*arg))
+ goto ng_name;
+ pev->group = strdup(*arg);
+ if (!pev->group)
+ return -ENOMEM;
+ *arg = ptr + 1;
+ } else
+ pev->group = NULL;
+ if (!is_c_func_name(*arg)) {
+ng_name:
+ semantic_error("%s is bad for event name -it must "
+ "follow C symbol-naming rule.\n", *arg);
+ return -EINVAL;
+ }
+ pev->event = strdup(*arg);
+ if (pev->event == NULL)
+ return -ENOMEM;
+
+ return 0;
+}
+
/* Parse probepoint definition. */
static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
{
@@ -1206,38 +1234,43 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
char *ptr, *tmp;
char c, nc = 0;
bool file_spec = false;
+ int ret;
+
/*
* <Syntax>
* perf probe [GRP:][EVENT=]SRC[:LN|;PTN]
* perf probe [GRP:][EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
+ * perf probe %[GRP:]SDT_EVENT
*/
if (!arg)
return -EINVAL;
+ if (arg[0] == '%') {
+ pev->sdt = true;
+ arg++;
+ }
+
ptr = strpbrk(arg, ";=@+%");
- if (ptr && *ptr == '=') { /* Event name */
- *ptr = '\0';
- tmp = ptr + 1;
- ptr = strchr(arg, ':');
+ if (pev->sdt) {
if (ptr) {
- *ptr = '\0';
- if (!is_c_func_name(arg))
- goto not_fname;
- pev->group = strdup(arg);
- if (!pev->group)
- return -ENOMEM;
- arg = ptr + 1;
- } else
- pev->group = NULL;
- if (!is_c_func_name(arg)) {
-not_fname:
- semantic_error("%s is bad for event name -it must "
- "follow C symbol-naming rule.\n", arg);
+ semantic_error("%s must contain only an SDT event name.\n", arg);
return -EINVAL;
}
- pev->event = strdup(arg);
- if (pev->event == NULL)
- return -ENOMEM;
+ ret = parse_perf_probe_event_name(&arg, pev);
+ if (ret == 0) {
+ if (asprintf(&pev->point.function, "%%%s", pev->event) < 0)
+ ret = -errno;
+ }
+ return ret;
+ }
+
+ if (ptr && *ptr == '=') { /* Event name */
+ *ptr = '\0';
+ tmp = ptr + 1;
+ ret = parse_perf_probe_event_name(&arg, pev);
+ if (ret < 0)
+ return ret;
+
arg = tmp;
}
@@ -2849,7 +2882,8 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
pev->point.function);
}
if (!entry) {
- ret = 0;
+ /* SDT must be in the cache */
+ ret = pev->sdt ? -ENOENT : 0;
goto out;
}
@@ -2888,7 +2922,7 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
{
int ret;
- if (!pev->group) {
+ if (!pev->group && !pev->sdt) {
/* Set group name if not given */
if (!pev->uprobes) {
pev->group = strdup(PERFPROBE_GROUP);
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index c451223..2a23efe 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -85,6 +85,7 @@ struct perf_probe_event {
char *group; /* Group name */
struct perf_probe_point point; /* Probe point */
int nargs; /* Number of arguments */
+ bool sdt; /* SDT/cached event flag */
bool uprobes; /* Uprobe event flag */
char *target; /* Target binary */
struct perf_probe_arg *args; /* Arguments */
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index c10a647..ee560dd 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -529,6 +529,15 @@ probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)
return NULL;
list_for_each_entry(entry, &pcache->list, list) {
+ if (pev->sdt) {
+ if (entry->pev.event &&
+ streql(entry->pev.event, pev->event) &&
+ (!pev->group ||
+ streql(entry->pev.group, pev->group)))
+ goto found;
+
+ continue;
+ }
/* Hit if same event name or same command-string */
if ((pev->event &&
(streql(entry->pev.group, pev->group) &&
[toc] | [prev] | [next] | [standalone]
| From | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| Date | 2016-04-28 07:30 +0200 |
| Subject | Re: [PATCH perf/core v5 11/15] perf probe: Accept %sdt and %cached event name |
| Message-ID | <rsMGu-68v-7@gated-at.bofh.it> |
| In reply to | #1389477 |
On Thu, Apr 28, 2016 at 03:38:49AM +0900, Masami Hiramatsu wrote:
> From: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
>
> To improbe usability, support %[PROVIDER:]SDTEVENT format to
> add new probes on SDT and cached events.
>
> e.g.
> ----
> # perf probe -x /lib/libc-2.17.so %lll_lock_wait_private
> Added new event:
> sdt_libc:lll_lock_wait_private (on %lll_lock_wait_private in
> /usr/lib/libc-2.17.so)
>
> You can now use it in all perf tools, such as:
>
> perf record -e sdt_libc:lll_lock_wait_private -aR sleep 1
>
> # perf probe -l | more
> sdt_libc:lll_lock_wait_private (on __lll_lock_wait_private+21
> in /usr/lib/libc-2.17.so)
> ----
>
> Note that this is not only for SDT events, but also normal
> events with event-name.
>
> e.g. define "myevent" on cache (-n doesn't add the real probe)
> ----
> # perf probe -x ./perf --cache -n --add 'myevent=dso__load $params'
> ----
> Reuse the "myevent" from cache as below.
> ----
> # perf probe -x ./perf %myevent
> ----
>
> TODO:
> Wildcard is not supported yet.
>
> Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> ---
> tools/perf/Documentation/perf-probe.txt | 3 +
> tools/perf/util/probe-event.c | 78 ++++++++++++++++++++++---------
> tools/perf/util/probe-event.h | 1
> tools/perf/util/probe-file.c | 9 ++++
> 4 files changed, 69 insertions(+), 22 deletions(-)
>
> diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
> index 7a258e9..43523be 100644
> --- a/tools/perf/Documentation/perf-probe.txt
> +++ b/tools/perf/Documentation/perf-probe.txt
> @@ -151,6 +151,8 @@ Probe points are defined by following syntax.
> 3) Define event based on source file with lazy pattern
> [[GROUP:]EVENT=]SRC;PTN [ARG ...]
>
> + 4) Pre-defined SDT events
> + %[PROVIDER:]SDTEVENT
How about changing it to:
4) Pre-defined (SDT) or cached events
%EVENTNAME
?
Btw, is it possible to use group name here? The SDT will use
sdt_<libname> for group name and <provider>_<event> for event name,
right? So is it for cached events and does it support defining group
name when added like below?
# perf probe -x ./perf --cache --add 'mygroup:myevent=main'
Thanks,
Namhyung
>
> 'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. You can also specify a group name by 'GROUP', if omitted, set 'probe' is used for kprobe and 'probe_<bin>' is used for uprobe.
> Note that using existing group name can conflict with other events. Especially, using the group name reserved for kernel modules can hide embedded events in the
> @@ -158,6 +160,7 @@ modules.
> 'FUNC' specifies a probed function name, and it may have one of the following options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is the relative-line number from function entry line, and '%return' means that it probes function return. And ';PTN' means lazy matching pattern (see LAZY MATCHING). Note that ';PTN' must be the end of the probe point definition. In addition, '@SRC' specifies a source file which has that function.
> It is also possible to specify a probe point by the source line number or lazy matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file path, ':ALN' is the line number and ';PTN' is the lazy matching pattern.
> 'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT).
> +'SDTEVENT' and 'PROVIDER' is the pre-defined event name which is defined by user SDT (Statically Defined Tracing) or the pre-cached probes with event name.
>
> PROBE ARGUMENT
> --------------
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index b2c6a4a..1a9ea2b 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -1199,6 +1199,34 @@ err:
> return err;
> }
>
> +static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev)
> +{
> + char *ptr;
> +
> + ptr = strchr(*arg, ':');
> + if (ptr) {
> + *ptr = '\0';
> + if (!is_c_func_name(*arg))
> + goto ng_name;
> + pev->group = strdup(*arg);
> + if (!pev->group)
> + return -ENOMEM;
> + *arg = ptr + 1;
> + } else
> + pev->group = NULL;
> + if (!is_c_func_name(*arg)) {
> +ng_name:
> + semantic_error("%s is bad for event name -it must "
> + "follow C symbol-naming rule.\n", *arg);
> + return -EINVAL;
> + }
> + pev->event = strdup(*arg);
> + if (pev->event == NULL)
> + return -ENOMEM;
> +
> + return 0;
> +}
> +
> /* Parse probepoint definition. */
> static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
> {
> @@ -1206,38 +1234,43 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
> char *ptr, *tmp;
> char c, nc = 0;
> bool file_spec = false;
> + int ret;
> +
> /*
> * <Syntax>
> * perf probe [GRP:][EVENT=]SRC[:LN|;PTN]
> * perf probe [GRP:][EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
> + * perf probe %[GRP:]SDT_EVENT
> */
> if (!arg)
> return -EINVAL;
>
> + if (arg[0] == '%') {
> + pev->sdt = true;
> + arg++;
> + }
> +
> ptr = strpbrk(arg, ";=@+%");
> - if (ptr && *ptr == '=') { /* Event name */
> - *ptr = '\0';
> - tmp = ptr + 1;
> - ptr = strchr(arg, ':');
> + if (pev->sdt) {
> if (ptr) {
> - *ptr = '\0';
> - if (!is_c_func_name(arg))
> - goto not_fname;
> - pev->group = strdup(arg);
> - if (!pev->group)
> - return -ENOMEM;
> - arg = ptr + 1;
> - } else
> - pev->group = NULL;
> - if (!is_c_func_name(arg)) {
> -not_fname:
> - semantic_error("%s is bad for event name -it must "
> - "follow C symbol-naming rule.\n", arg);
> + semantic_error("%s must contain only an SDT event name.\n", arg);
> return -EINVAL;
> }
> - pev->event = strdup(arg);
> - if (pev->event == NULL)
> - return -ENOMEM;
> + ret = parse_perf_probe_event_name(&arg, pev);
> + if (ret == 0) {
> + if (asprintf(&pev->point.function, "%%%s", pev->event) < 0)
> + ret = -errno;
> + }
> + return ret;
> + }
> +
> + if (ptr && *ptr == '=') { /* Event name */
> + *ptr = '\0';
> + tmp = ptr + 1;
> + ret = parse_perf_probe_event_name(&arg, pev);
> + if (ret < 0)
> + return ret;
> +
> arg = tmp;
> }
>
> @@ -2849,7 +2882,8 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
> pev->point.function);
> }
> if (!entry) {
> - ret = 0;
> + /* SDT must be in the cache */
> + ret = pev->sdt ? -ENOENT : 0;
> goto out;
> }
>
> @@ -2888,7 +2922,7 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
> {
> int ret;
>
> - if (!pev->group) {
> + if (!pev->group && !pev->sdt) {
> /* Set group name if not given */
> if (!pev->uprobes) {
> pev->group = strdup(PERFPROBE_GROUP);
> diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
> index c451223..2a23efe 100644
> --- a/tools/perf/util/probe-event.h
> +++ b/tools/perf/util/probe-event.h
> @@ -85,6 +85,7 @@ struct perf_probe_event {
> char *group; /* Group name */
> struct perf_probe_point point; /* Probe point */
> int nargs; /* Number of arguments */
> + bool sdt; /* SDT/cached event flag */
> bool uprobes; /* Uprobe event flag */
> char *target; /* Target binary */
> struct perf_probe_arg *args; /* Arguments */
> diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
> index c10a647..ee560dd 100644
> --- a/tools/perf/util/probe-file.c
> +++ b/tools/perf/util/probe-file.c
> @@ -529,6 +529,15 @@ probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)
> return NULL;
>
> list_for_each_entry(entry, &pcache->list, list) {
> + if (pev->sdt) {
> + if (entry->pev.event &&
> + streql(entry->pev.event, pev->event) &&
> + (!pev->group ||
> + streql(entry->pev.group, pev->group)))
> + goto found;
> +
> + continue;
> + }
> /* Hit if same event name or same command-string */
> if ((pev->event &&
> (streql(entry->pev.group, pev->group) &&
>
[toc] | [prev] | [next] | [standalone]
| From | Masami Hiramatsu <mhiramat@kernel.org> |
|---|---|
| Date | 2016-04-29 02:20 +0200 |
| Subject | Re: [PATCH perf/core v5 11/15] perf probe: Accept %sdt and %cached event name |
| Message-ID | <rt4k1-4Rw-5@gated-at.bofh.it> |
| In reply to | #1389791 |
On Thu, 28 Apr 2016 14:26:05 +0900
Namhyung Kim <namhyung@kernel.org> wrote:
> On Thu, Apr 28, 2016 at 03:38:49AM +0900, Masami Hiramatsu wrote:
> > From: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> >
> > To improbe usability, support %[PROVIDER:]SDTEVENT format to
> > add new probes on SDT and cached events.
> >
> > e.g.
> > ----
> > # perf probe -x /lib/libc-2.17.so %lll_lock_wait_private
> > Added new event:
> > sdt_libc:lll_lock_wait_private (on %lll_lock_wait_private in
> > /usr/lib/libc-2.17.so)
> >
> > You can now use it in all perf tools, such as:
> >
> > perf record -e sdt_libc:lll_lock_wait_private -aR sleep 1
> >
> > # perf probe -l | more
> > sdt_libc:lll_lock_wait_private (on __lll_lock_wait_private+21
> > in /usr/lib/libc-2.17.so)
> > ----
> >
> > Note that this is not only for SDT events, but also normal
> > events with event-name.
> >
> > e.g. define "myevent" on cache (-n doesn't add the real probe)
> > ----
> > # perf probe -x ./perf --cache -n --add 'myevent=dso__load $params'
> > ----
> > Reuse the "myevent" from cache as below.
> > ----
> > # perf probe -x ./perf %myevent
> > ----
> >
> > TODO:
> > Wildcard is not supported yet.
> >
> > Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> > ---
> > tools/perf/Documentation/perf-probe.txt | 3 +
> > tools/perf/util/probe-event.c | 78 ++++++++++++++++++++++---------
> > tools/perf/util/probe-event.h | 1
> > tools/perf/util/probe-file.c | 9 ++++
> > 4 files changed, 69 insertions(+), 22 deletions(-)
> >
> > diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
> > index 7a258e9..43523be 100644
> > --- a/tools/perf/Documentation/perf-probe.txt
> > +++ b/tools/perf/Documentation/perf-probe.txt
> > @@ -151,6 +151,8 @@ Probe points are defined by following syntax.
> > 3) Define event based on source file with lazy pattern
> > [[GROUP:]EVENT=]SRC;PTN [ARG ...]
> >
> > + 4) Pre-defined SDT events
> > + %[PROVIDER:]SDTEVENT
>
> How about changing it to:
>
> 4) Pre-defined (SDT) or cached events
> %EVENTNAME
>
> ?
Agreed, because cached events can be used for that too.
I think %[GROUP:]EVENT is more accurate.
> Btw, is it possible to use group name here?
Yes :)
> The SDT will use
> sdt_<libname> for group name and <provider>_<event> for event name,
> right?
No, the provider name is used for the group name as "sdt_<provider>".
> So is it for cached events and does it support defining group
> name when added like below?
>
> # perf probe -x ./perf --cache --add 'mygroup:myevent=main'
Yes, it is done by 9/15 ("perf probe: Add group name support") :)
Thank you,
--
Masami Hiramatsu <mhiramat@kernel.org>
[toc] | [prev] | [next] | [standalone]
| From | Masami Hiramatsu <mhiramat@kernel.org> |
|---|---|
| Date | 2016-04-27 20:40 +0200 |
| Subject | [PATCH perf/core v5 09/15] perf probe: Add group name support |
| Message-ID | <rsCxu-5Ye-65@gated-at.bofh.it> |
| In reply to | #1389465 |
From: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Allow user to set group name for adding new event.
Note that user must ensure that the group name doesn't
conflict with existing group name carefully.
E.g. Existing group name can conflict with other events.
Especially, using the group name reserved for kernel
modules can hide kernel embedded events when loading
modules.
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
Changes in v4:
- Update Documentation/perf-probe.txt too.
---
tools/perf/Documentation/perf-probe.txt | 10 ++++++----
tools/perf/util/probe-event.c | 23 ++++++++++++++---------
2 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 8d09173..7a258e9 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -143,16 +143,18 @@ PROBE SYNTAX
Probe points are defined by following syntax.
1) Define event based on function name
- [EVENT=]FUNC[@SRC][:RLN|+OFFS|%return|;PTN] [ARG ...]
+ [[GROUP:]EVENT=]FUNC[@SRC][:RLN|+OFFS|%return|;PTN] [ARG ...]
2) Define event based on source file with line number
- [EVENT=]SRC:ALN [ARG ...]
+ [[GROUP:]EVENT=]SRC:ALN [ARG ...]
3) Define event based on source file with lazy pattern
- [EVENT=]SRC;PTN [ARG ...]
+ [[GROUP:]EVENT=]SRC;PTN [ARG ...]
-'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. Currently, event group name is set as 'probe'.
+'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. You can also specify a group name by 'GROUP', if omitted, set 'probe' is used for kprobe and 'probe_<bin>' is used for uprobe.
+Note that using existing group name can conflict with other events. Especially, using the group name reserved for kernel modules can hide embedded events in the
+modules.
'FUNC' specifies a probed function name, and it may have one of the following options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is the relative-line number from function entry line, and '%return' means that it probes function return. And ';PTN' means lazy matching pattern (see LAZY MATCHING). Note that ';PTN' must be the end of the probe point definition. In addition, '@SRC' specifies a source file which has that function.
It is also possible to specify a probe point by the source line number or lazy matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file path, ':ALN' is the line number and ';PTN' is the lazy matching pattern.
'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT).
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 8bea724..b2c6a4a 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1208,10 +1208,8 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
bool file_spec = false;
/*
* <Syntax>
- * perf probe [EVENT=]SRC[:LN|;PTN]
- * perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
- *
- * TODO:Group name support
+ * perf probe [GRP:][EVENT=]SRC[:LN|;PTN]
+ * perf probe [GRP:][EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
*/
if (!arg)
return -EINVAL;
@@ -1220,11 +1218,19 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
if (ptr && *ptr == '=') { /* Event name */
*ptr = '\0';
tmp = ptr + 1;
- if (strchr(arg, ':')) {
- semantic_error("Group name is not supported yet.\n");
- return -ENOTSUP;
- }
+ ptr = strchr(arg, ':');
+ if (ptr) {
+ *ptr = '\0';
+ if (!is_c_func_name(arg))
+ goto not_fname;
+ pev->group = strdup(arg);
+ if (!pev->group)
+ return -ENOMEM;
+ arg = ptr + 1;
+ } else
+ pev->group = NULL;
if (!is_c_func_name(arg)) {
+not_fname:
semantic_error("%s is bad for event name -it must "
"follow C symbol-naming rule.\n", arg);
return -EINVAL;
@@ -1232,7 +1238,6 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
pev->event = strdup(arg);
if (pev->event == NULL)
return -ENOMEM;
- pev->group = NULL;
arg = tmp;
}
[toc] | [prev] | [next] | [standalone]
| From | Hemant Kumar <hemant@linux.vnet.ibm.com> |
|---|---|
| Date | 2016-04-29 16:00 +0200 |
| Message-ID | <rth7z-6Yb-11@gated-at.bofh.it> |
| In reply to | #1389465 |
Hi Masami, On 04/28/2016 12:07 AM, Masami Hiramatsu wrote: > Hi, > > Here is the 5th version of the patchset for probe-cache and > initial SDT support which are going to be perf-cache finally. > > The previous version is here; https://lkml.org/lkml/2016/4/26/179 > > This version fixes a build bug on "make build-test", removed > accepted patches, and fold buildid-cache style change and backward > compatibility patches. > IOW, just a cleanup version :) > > TODOs are here, but I think it should involve kernel-side change > to complete. > - (perf record) Support SDT event recording directly > - (perf record) Support @FILE/@BUILDID suffix to record specific SDTs. > - (perf record) Try to unregister SDT events after record. I just sent a patch enabling direct recording on SDT events implementing 1st and 3rd TODOs of the above list. Its based on your patches. Let me know your thoughts on the same. -- Thanks, Hemant Kumar > - (ftrace) Support multiple SDTs on single event. > > Thank you, > > --- > > Hemant Kumar (1): > perf/sdt: ELF support for SDT > > Masami Hiramatsu (14): > perf probe: Use strbuf for making strings > perf-buildid-cache: Use path/to/bin/buildid/elf instead of path/to/bin/buildid > perf-buildid-cache: Use lsdir for looking up buildid caches > perf probe: Add --cache option to cache the probe definitions > perf probe: Use cache entry if possible > perf probe: Show all cached probes > perf probe: Remove caches when --cache is given > perf probe: Add group name support > perf buildid-cache: Scan and import user SDT events to probe cache > perf probe: Accept %sdt and %cached event name > perf-list: Show SDT and pre-cached events > perf-list: Skip SDTs placed in invalid binaries > perf probe: Allow wildcard for cached events > perf probe: Support @BUILDID or @FILE suffix for SDT events > > > tools/perf/Documentation/perf-probe.txt | 24 + > tools/perf/builtin-list.c | 4 > tools/perf/builtin-probe.c | 30 + > tools/perf/util/build-id.c | 278 ++++++++++--- > tools/perf/util/build-id.h | 6 > tools/perf/util/dso.h | 5 > tools/perf/util/parse-events.c | 83 ++++ > tools/perf/util/parse-events.h | 2 > tools/perf/util/probe-event.c | 684 ++++++++++++++++++++++--------- > tools/perf/util/probe-event.h | 9 > tools/perf/util/probe-file.c | 492 ++++++++++++++++++++++ > tools/perf/util/probe-file.h | 41 ++ > tools/perf/util/probe-finder.c | 14 - > tools/perf/util/symbol-elf.c | 252 +++++++++++ > tools/perf/util/symbol.c | 15 - > tools/perf/util/symbol.h | 22 + > 16 files changed, 1689 insertions(+), 272 deletions(-) > > -- > Masami Hiramatsu >
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | linux.kernel
csiph-web