Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753931AbbHOLuY (ORCPT ); Sat, 15 Aug 2015 07:50:24 -0400 Received: from mail9.hitachi.co.jp ([133.145.228.44]:44061 "EHLO mail9.hitachi.co.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752499AbbHOLsI (ORCPT ); Sat, 15 Aug 2015 07:48:08 -0400 X-AuditID: 85900ec0-9cdc8b9000001a57-37-55cf26a35484 Subject: [RFC PATCH perf/core v3 14/17] perf probe: Accept %sdt and %cached event name From: Masami Hiramatsu To: Arnaldo Carvalho de Melo Cc: Peter Zijlstra , linux-kernel@vger.kernel.org, Adrian Hunter , Ingo Molnar , Paul Mackerras , Jiri Olsa , Namhyung Kim , Borislav Petkov , Hemant Kumar Date: Sat, 15 Aug 2015 20:43:23 +0900 Message-ID: <20150815114323.13642.42503.stgit@localhost.localdomain> In-Reply-To: <20150815114252.13642.62690.stgit@localhost.localdomain> References: <20150815114252.13642.62690.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: 7140 Lines: 221 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 --- 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 8d09173..1d38221 100644 --- a/tools/perf/Documentation/perf-probe.txt +++ b/tools/perf/Documentation/perf-probe.txt @@ -151,11 +151,14 @@ Probe points are defined by following syntax. 3) Define event based on source file with lazy pattern [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. Currently, event group name is set as 'probe'. '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 c559f01..92e800e 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -1132,6 +1132,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) { @@ -1139,38 +1167,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; + /* * * 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; } @@ -2620,7 +2653,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; } @@ -2659,7 +2693,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 fdea725..2cd60e6 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h @@ -84,6 +84,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 7e2b4f8..018c443 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -504,6 +504,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) && -- 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/