From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Masami Hiramatsu <mhiramat@kernel.org>
Cc: linux-kernel@vger.kernel.org, Namhyung Kim <namhyung@kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Hemant Kumar <hemant@linux.vnet.ibm.com>,
Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>,
Brendan Gregg <brendan.d.gregg@gmail.com>
Subject: Re: [PATCH perf/core 05/10] perf probe: Allow wildcard for cached events
Date: Wed, 13 Jul 2016 16:36:14 -0300 [thread overview]
Message-ID: <20160713193614.GG27879@kernel.org> (raw)
In-Reply-To: <146831791813.17065.17846564230840594888.stgit@devbox>
Em Tue, Jul 12, 2016 at 07:05:18PM +0900, Masami Hiramatsu escreveu:
> Allo glob wildcard for reusing cached/SDT events. E.g.
>
> # perf probe -x /usr/lib64/libc-2.20.so -a %sdt_libc:\*
The example message for this could be improved to also use a wildcard
:-)
> 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 v12:
> - Rename strlist__for_each to strlist__for_each_entry.
> Changes in v10:
> - Split off bugfix, adding interface, and target search patches.
> - Do not export clear_probe_trace_events().
> Changes in v7:
> - Continue to search caches if a build-id cache has no probe cache.
> - Make probe_cache__open() to accept DSO__NAME_KALLSYMS for kernel.
> - Fix to add probes correctly when a wildcard matchs both of
> uprobes and kprobes.
> Changes in v5.1:
> - Fix a SEGV bug when a group name is omitted. (Thanks Hemant!)
> ---
> tools/perf/util/probe-event.c | 107 +++++++++++++++++++++++++++++++++++++++--
> tools/perf/util/probe-file.c | 38 ++++++++++++---
> tools/perf/util/probe-file.h | 3 +
> 3 files changed, 138 insertions(+), 10 deletions(-)
>
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index 3642cca..1aeac09 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -1204,7 +1204,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)
> @@ -1212,7 +1212,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);
> @@ -1644,6 +1644,7 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev)
> ret = -ENOMEM;
> goto out;
> }
> + tev->uprobes = (tp->module[0] == '/');
> p++;
> } else
> p = argv[1];
> @@ -2518,7 +2519,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;
> @@ -2531,7 +2532,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;
> @@ -2894,6 +2895,100 @@ 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. Return the number
> + * of cached events found, if an error occurs return the error.
> + */
> +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);
> + /* Return 0 ("not found") if the target has no probe cache. */
> + if (!cache)
> + return 0;
> +
> + 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 (ntevs > 0 && target && target[0] == '/')
> + pev->uprobes = true;
> + }
> +
> + return ret;
> +}
> +
> static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
> struct probe_trace_event **tevs)
> {
> @@ -2903,6 +2998,10 @@ 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 */
> + 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-file.c b/tools/perf/util/probe-file.c
> index 9152ad2..78a84f5 100644
> --- a/tools/perf/util/probe-file.c
> +++ b/tools/perf/util/probe-file.c
> @@ -362,13 +362,38 @@ probe_cache_entry__new(struct perf_probe_event *pev)
> return entry;
> }
>
> -/* For the kernel probe caches, pass target = NULL */
> +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_entry(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 or DSO__NAME_KALLSYMS */
> static int probe_cache__open(struct probe_cache *pcache, const char *target)
> {
> char cpath[PATH_MAX];
> char sbuildid[SBUILD_ID_SIZE];
> char *dir_name = NULL;
> - bool is_kallsyms = !target;
> + bool is_kallsyms = false;
> int ret, fd;
>
> if (target && build_id_cache__cached(target)) {
> @@ -378,12 +403,13 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target)
> goto found;
> }
>
> - if (target)
> - ret = filename__sprintf_build_id(target, sbuildid);
> - else {
> + if (!target || !strcmp(target, DSO__NAME_KALLSYMS)) {
> target = DSO__NAME_KALLSYMS;
> + is_kallsyms = true;
> ret = sysfs__sprintf_build_id("/", sbuildid);
> - }
> + } else
> + ret = filename__sprintf_build_id(target, sbuildid);
> +
> if (ret < 0) {
> pr_debug("Failed to get build-id from %s.\n", target);
> return ret;
> diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
> index d513b34..cafbe1d 100644
> --- a/tools/perf/util/probe-file.h
> +++ b/tools/perf/util/probe-file.h
> @@ -34,6 +34,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,
next prev parent reply other threads:[~2016-07-13 19:36 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-12 10:04 [PATCH perf/core 00/10] perf-probe --cache and SDT support Masami Hiramatsu
2016-07-12 10:04 ` [PATCH perf/core 01/10] [BUGFIX] perf-probe: Fix to show correct error message for $vars and $params Masami Hiramatsu
2016-07-14 7:05 ` [tip:perf/core] perf probe: " tip-bot for Masami Hiramatsu
2016-07-12 10:04 ` [PATCH perf/core 02/10] perf probe: Accept %sdt and %cached event name Masami Hiramatsu
2016-07-14 7:05 ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2016-07-12 10:04 ` [PATCH perf/core 03/10] perf-probe: Make --list shows only available cached events Masami Hiramatsu
2016-07-13 19:28 ` Arnaldo Carvalho de Melo
2016-07-14 6:13 ` Masami Hiramatsu
2016-07-14 7:06 ` [tip:perf/core] perf probe: Make --list show " tip-bot for Masami Hiramatsu
2016-07-12 10:05 ` [PATCH perf/core 04/10] perf: probe-cache: Add for_each_probe_cache_entry() wrapper Masami Hiramatsu
2016-07-14 7:06 ` [tip:perf/core] perf " tip-bot for Masami Hiramatsu
2016-07-12 10:05 ` [PATCH perf/core 05/10] perf probe: Allow wildcard for cached events Masami Hiramatsu
2016-07-13 19:36 ` Arnaldo Carvalho de Melo [this message]
2016-07-14 7:07 ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2016-07-12 10:05 ` [PATCH perf/core 06/10] perf probe: Search SDT/cached event from all probe caches Masami Hiramatsu
2016-07-14 7:07 ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2016-07-12 10:05 ` [PATCH perf/core 07/10] perf probe: Support @BUILDID or @FILE suffix for SDT events Masami Hiramatsu
2016-07-13 19:50 ` Arnaldo Carvalho de Melo
2016-07-14 0:07 ` Arnaldo Carvalho de Melo
2016-07-14 0:16 ` Arnaldo Carvalho de Melo
2016-07-14 0:20 ` Arnaldo Carvalho de Melo
2016-07-14 15:32 ` Masami Hiramatsu
2016-07-14 7:08 ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2016-07-12 10:05 ` [PATCH perf/core 08/10] perf probe: Support a special SDT probe format Masami Hiramatsu
2016-07-14 7:08 ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2016-07-12 10:05 ` [PATCH perf/core 09/10] perf build: Add sdt feature detection Masami Hiramatsu
2016-07-14 7:09 ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2016-07-12 10:06 ` [PATCH perf/core 10/10] perf-test: Add a test case for SDT event Masami Hiramatsu
2016-07-14 7:10 ` [tip:perf/core] perf test: " tip-bot for Masami Hiramatsu
2016-07-14 1:35 ` [PATCH perf/core 00/10] perf-probe --cache and SDT support Arnaldo Carvalho de Melo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160713193614.GG27879@kernel.org \
--to=acme@kernel.org \
--cc=ananth@linux.vnet.ibm.com \
--cc=brendan.d.gregg@gmail.com \
--cc=hemant@linux.vnet.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mhiramat@kernel.org \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.