Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965217AbbDWNsh (ORCPT ); Thu, 23 Apr 2015 09:48:37 -0400 Received: from mail9.hitachi.co.jp ([133.145.228.44]:33608 "EHLO mail9.hitachi.co.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S964918AbbDWNs0 (ORCPT ); Thu, 23 Apr 2015 09:48:26 -0400 X-AuditID: 85900ec0-a14c8b9000003d4c-f7-5538f81e1e17 Subject: [PATCH perf/core v2 4/8] perf probe: Accept filter argument for --list From: Masami Hiramatsu To: Arnaldo Carvalho de Melo Cc: Peter Zijlstra , Linux Kernel Mailing List , David Ahern , namhyung@kernel.org, Jiri Olsa , Ingo Molnar Date: Thu, 23 Apr 2015 22:46:19 +0900 Message-ID: <20150423134619.26128.9144.stgit@localhost.localdomain> In-Reply-To: <20150423134610.26128.82557.stgit@localhost.localdomain> References: <20150423134610.26128.82557.stgit@localhost.localdomain> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Brightmail-Tracker: AAAAAA== Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 8467 Lines: 266 Currently, perf-probe --list option ignores given event filter. ---- # ./perf probe -l vfs\* probe:vfs_read (on vfs_read@ksrc/linux-3/fs/read_write.c) probe_libc:malloc (on __libc_malloc@malloc/malloc.c in /usr/lib64/libc-2.17.so) ---- This changes --list option to accept the event filter argument as below. ---- # ./perf probe -l vfs\* probe:vfs_read (on vfs_read@ksrc/linux-3/fs/read_write.c) # ./perf probe -l \*libc:\* probe_libc:malloc (on __libc_malloc@malloc/malloc.c in /usr/lib64/libc-2.17.so) ---- Signed-off-by: Masami Hiramatsu --- tools/perf/Documentation/perf-probe.txt | 6 +-- tools/perf/builtin-probe.c | 70 ++++++++++++++++++++----------- tools/perf/util/probe-event.c | 27 ++++++++++-- tools/perf/util/probe-event.h | 2 - 4 files changed, 73 insertions(+), 32 deletions(-) diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt index a4a3cc7..d0feb8e 100644 --- a/tools/perf/Documentation/perf-probe.txt +++ b/tools/perf/Documentation/perf-probe.txt @@ -14,7 +14,7 @@ or or 'perf probe' [options] --del='[GROUP:]EVENT' [...] or -'perf probe' --list +'perf probe' --list[=[GROUP:]EVENT] or 'perf probe' [options] --line='LINE' or @@ -66,8 +66,8 @@ OPTIONS classes(e.g. [a-z], [!A-Z]). -l:: ---list:: - List up current probe events. +--list[=[GROUP:]EVENT]:: + List up current probe events. This can also accept filtering patterns of event names. -L:: --line=:: diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index be17075..feca316 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -44,6 +44,7 @@ #define DEFAULT_VAR_FILTER "!__k???tab_* & !__crc_*" #define DEFAULT_FUNC_FILTER "!_*" +#define DEFAULT_LIST_FILTER "*:*" /* Session management structure */ static struct { @@ -93,6 +94,28 @@ static int parse_probe_event(const char *str) return ret; } +static int params_add_filter(const char *str) +{ + const char *err = NULL; + int ret = 0; + + pr_debug2("Add filter: %s\n", str); + if (!params.filter) { + params.filter = strfilter__new(str, &err); + if (!params.filter) + ret = err ? -EINVAL : -ENOMEM; + } else + ret = strfilter__or(params.filter, str, &err); + + if (ret == -EINVAL) { + pr_err("Filter parse error at %td.\n", err - str + 1); + pr_err("Source: \"%s\"\n", str); + pr_err(" %*c\n", (int)(err - str + 1), '^'); + } + + return ret; +} + static int set_target(const char *ptr) { int found = 0; @@ -180,6 +203,18 @@ static int opt_del_probe_event(const struct option *opt __maybe_unused, return 0; } +static int opt_list_probe_event(const struct option *opt __maybe_unused, + const char *str, int unset) +{ + if (!unset) + params.list_events = true; + + if (str) + return params_add_filter(str); + + return 0; +} + static int opt_set_target(const struct option *opt, const char *str, int unset __maybe_unused) { @@ -261,26 +296,10 @@ static int opt_show_vars(const struct option *opt __maybe_unused, static int opt_set_filter(const struct option *opt __maybe_unused, const char *str, int unset __maybe_unused) { - const char *err; - int ret = 0; + if (str) + return params_add_filter(str); - if (str) { - pr_debug2("Set filter: %s\n", str); - if (!params.filter) { - params.filter = strfilter__new(str, &err); - if (!params.filter) - ret = err ? -EINVAL : -ENOMEM; - } else - ret = strfilter__or(params.filter, str, &err); - - if (ret == -EINVAL) { - pr_err("Filter parse error at %td.\n", err - str + 1); - pr_err("Source: \"%s\"\n", str); - pr_err(" %*c\n", (int)(err - str + 1), '^'); - } - } - - return ret; + return 0; } static int init_params(void) @@ -320,21 +339,22 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) "perf probe [] 'PROBEDEF' ['PROBEDEF' ...]", "perf probe [] --add 'PROBEDEF' [--add 'PROBEDEF' ...]", "perf probe [] --del '[GROUP:]EVENT' ...", - "perf probe --list", + "perf probe --list [GROUP:]EVENT ...", #ifdef HAVE_DWARF_SUPPORT "perf probe [] --line 'LINEDESC'", "perf probe [] --vars 'PROBEPOINT'", #endif "perf probe [] --funcs", NULL -}; + }; struct option options[] = { OPT_INCR('v', "verbose", &verbose, "be more verbose (show parsed arguments, etc)"), OPT_BOOLEAN('q', "quiet", ¶ms.quiet, "be quiet (do not show any mesages)"), - OPT_BOOLEAN('l', "list", ¶ms.list_events, - "list up current probe events"), + OPT_CALLBACK_DEFAULT('l', "list", NULL, "[GROUP:]EVENT", + "list up probe events", opt_list_probe_event, + DEFAULT_LIST_FILTER), OPT_CALLBACK('d', "del", NULL, "[GROUP:]EVENT", "delete a probe event.", opt_del_probe_event), OPT_CALLBACK('a', "add", NULL, @@ -448,7 +468,9 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) pr_warning(" Error: Don't use --list with --exec.\n"); usage_with_options(probe_usage, options); } - ret = show_perf_probe_events(); + ret = show_perf_probe_events(params.filter); + strfilter__delete(params.filter); + params.filter = NULL; if (ret < 0) pr_err_with_code(" Error: Failed to show event list.", ret); return ret; diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 291bf23..acd9ec8 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -2129,7 +2129,23 @@ static int show_perf_probe_event(struct perf_probe_event *pev, return ret; } -static int __show_perf_probe_events(int fd, bool is_kprobe) +static bool filter_probe_trace_event(struct probe_trace_event *tev, + struct strfilter *filter) +{ + char tmp[128]; + + /* At first, check the event name itself */ + if (strfilter__compare(filter, tev->event)) + return true; + + /* Next, check the combination of name and group */ + if (e_snprintf(tmp, 128, "%s:%s", tev->group, tev->event) < 0) + return false; + return strfilter__compare(filter, tmp); +} + +static int __show_perf_probe_events(int fd, bool is_kprobe, + struct strfilter *filter) { int ret = 0; struct probe_trace_event tev; @@ -2147,12 +2163,15 @@ static int __show_perf_probe_events(int fd, bool is_kprobe) strlist__for_each(ent, rawlist) { ret = parse_probe_trace_command(ent->s, &tev); if (ret >= 0) { + if (!filter_probe_trace_event(&tev, filter)) + goto next; ret = convert_to_perf_probe_event(&tev, &pev, is_kprobe); if (ret >= 0) ret = show_perf_probe_event(&pev, tev.point.module); } +next: clear_perf_probe_event(&pev); clear_probe_trace_event(&tev); if (ret < 0) @@ -2164,7 +2183,7 @@ static int __show_perf_probe_events(int fd, bool is_kprobe) } /* List up current perf-probe events */ -int show_perf_probe_events(void) +int show_perf_probe_events(struct strfilter *filter) { int kp_fd, up_fd, ret; @@ -2176,7 +2195,7 @@ int show_perf_probe_events(void) kp_fd = open_kprobe_events(false); if (kp_fd >= 0) { - ret = __show_perf_probe_events(kp_fd, true); + ret = __show_perf_probe_events(kp_fd, true, filter); close(kp_fd); if (ret < 0) goto out; @@ -2190,7 +2209,7 @@ int show_perf_probe_events(void) } if (up_fd >= 0) { - ret = __show_perf_probe_events(up_fd, false); + ret = __show_perf_probe_events(up_fd, false, filter); close(up_fd); } out: diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index d6b7834..819e825 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h @@ -127,7 +127,7 @@ extern const char *kernel_get_module_path(const char *module); extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, int max_probe_points, bool force_add); extern int del_perf_probe_events(struct strlist *dellist); -extern int show_perf_probe_events(void); +extern int show_perf_probe_events(struct strfilter *filter); extern int show_line_range(struct line_range *lr, const char *module, bool user); extern int show_available_vars(struct perf_probe_event *pevs, int npevs, -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/