From: Masami Hiramatsu <mhiramat@kernel.org>
To: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>,
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: [PATCH perf/core v11 13/20] perf buildid-cache: Scan and import user SDT events to probe cache
Date: Wed, 15 Jun 2016 12:29:43 +0900 [thread overview]
Message-ID: <20160615032943.31330.58104.stgit@devbox> (raw)
In-Reply-To: <20160615032728.31330.45150.stgit@devbox>
From: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
perf buildid-cache --add <binary> scans given binary and add
the SDT events to probe cache. "sdt_" prefix is appended for
all SDT providers to avoid event-name clash with other pre-defined
events. It is possible to use the cached SDT events as other cached
events, via perf probe --add "sdt_<provider>:<event>=<event>".
e.g.
----
# perf buildid-cache --add /lib/libc-2.17.so
# perf probe --cache --list | head -n 5
/usr/lib/libc-2.17.so (a6fb821bdf53660eb2c29f778757aef294d3d392):
sdt_libc:setjmp=setjmp
sdt_libc:longjmp=longjmp
sdt_libc:longjmp_target=longjmp_target
sdt_libc:memory_heap_new=memory_heap_new
# perf probe -x /usr/lib/libc-2.17.so \
-a sdt_libc:memory_heap_new=memory_heap_new
Added new event:
sdt_libc:memory_heap_new (on memory_heap_new
in /usr/lib/libc-2.17.so)
You can now use it in all perf tools, such as:
perf record -e sdt_libc:memory_heap_new -aR sleep 1
# perf probe -l
sdt_libc:memory_heap_new (on new_heap+183 in /usr/lib/libc-2.17.so)
----
Note that SDT event entries in probe-cache file is somewhat different
from normal cached events. Normal one starts with "#", but SDTs are
starting with "%".
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
Changes in v11:
- Warn if SDT scanning/updating are failed.
Changes in v10:
- Update Documentation/perf-buildid-cache.txt too.
Changes in v4:
- Fix a bug to copy correct group name to entries.
- Fix to consolidate same-name entries.
---
tools/perf/Documentation/perf-buildid-cache.txt | 3 +
tools/perf/util/build-id.c | 30 ++++++++++
tools/perf/util/probe-file.c | 69 ++++++++++++++++++++++-
tools/perf/util/probe-file.h | 2 +
4 files changed, 101 insertions(+), 3 deletions(-)
diff --git a/tools/perf/Documentation/perf-buildid-cache.txt b/tools/perf/Documentation/perf-buildid-cache.txt
index dd07b55..058064d 100644
--- a/tools/perf/Documentation/perf-buildid-cache.txt
+++ b/tools/perf/Documentation/perf-buildid-cache.txt
@@ -15,6 +15,9 @@ DESCRIPTION
This command manages the build-id cache. It can add, remove, update and purge
files to/from the cache. In the future it should as well set upper limits for
the space used by the cache, etc.
+This also scans the target binary for SDT (Statically Defined Tracing) and
+record it along with the buildid-cache, which will be used by perf-probe.
+For more details, see linkperf:perf-probe[1].
OPTIONS
-------
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 0d6093c..95d4490 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -17,6 +17,7 @@
#include "tool.h"
#include "header.h"
#include "vdso.h"
+#include "probe-file.h"
static bool no_buildid_cache;
@@ -532,6 +533,30 @@ int build_id_cache__list_build_ids(const char *pathname,
return ret;
}
+#ifdef HAVE_LIBELF_SUPPORT
+static int build_id_cache__add_sdt_cache(const char *sbuild_id,
+ const char *realname)
+{
+ struct probe_cache *cache;
+ int ret;
+
+ cache = probe_cache__new(sbuild_id);
+ if (!cache)
+ return -1;
+
+ ret = probe_cache__scan_sdt(cache, realname);
+ if (ret >= 0) {
+ pr_debug("Found %d SDTs in %s\n", ret, realname);
+ if (probe_cache__commit(cache) < 0)
+ ret = -1;
+ }
+ probe_cache__delete(cache);
+ return ret;
+}
+#else
+#define build_id_cache__add_sdt_cache(sbuild_id, realname) (0)
+#endif
+
int build_id_cache__add_s(const char *sbuild_id, const char *name,
bool is_kallsyms, bool is_vdso)
{
@@ -589,6 +614,11 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name,
if (symlink(tmp, linkname) == 0)
err = 0;
+
+ /* Update SDT cache : error is just warned */
+ if (build_id_cache__add_sdt_cache(sbuild_id, realname) < 0)
+ pr_debug("Failed to update/scan SDT cache for %s\n", realname);
+
out_free:
if (!is_kallsyms)
free(realname);
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index f8f710e..0f544bd 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -434,12 +434,15 @@ static int probe_cache__load(struct probe_cache *pcache)
p = strchr(buf, '\n');
if (p)
*p = '\0';
- if (buf[0] == '#') { /* #perf_probe_event */
+ /* #perf_probe_event or %sdt_event */
+ if (buf[0] == '#' || buf[0] == '%') {
entry = probe_cache_entry__new(NULL);
if (!entry) {
ret = -ENOMEM;
goto out;
}
+ if (buf[0] == '%')
+ entry->sdt = true;
entry->spev = strdup(buf + 1);
if (entry->spev)
ret = parse_perf_probe_command(buf + 1,
@@ -621,19 +624,79 @@ out_err:
return ret;
}
+static unsigned long long sdt_note__get_addr(struct sdt_note *note)
+{
+ return note->bit32 ? (unsigned long long)note->addr.a32[0]
+ : (unsigned long long)note->addr.a64[0];
+}
+
+int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname)
+{
+ struct probe_cache_entry *entry = NULL;
+ struct list_head sdtlist;
+ struct sdt_note *note;
+ char *buf;
+ char sdtgrp[64];
+ int ret;
+
+ INIT_LIST_HEAD(&sdtlist);
+ ret = get_sdt_note_list(&sdtlist, pathname);
+ if (ret < 0) {
+ pr_debug("Failed to get sdt note: %d\n", ret);
+ return ret;
+ }
+ list_for_each_entry(note, &sdtlist, note_list) {
+ ret = snprintf(sdtgrp, 64, "sdt_%s", note->provider);
+ if (ret < 0)
+ break;
+ /* Try to find same-name entry */
+ entry = probe_cache__find_by_name(pcache, sdtgrp, note->name);
+ if (!entry) {
+ entry = probe_cache_entry__new(NULL);
+ if (!entry) {
+ ret = -ENOMEM;
+ break;
+ }
+ entry->sdt = true;
+ ret = asprintf(&entry->spev, "%s:%s=%s", sdtgrp,
+ note->name, note->name);
+ if (ret < 0)
+ break;
+ entry->pev.event = strdup(note->name);
+ entry->pev.group = strdup(sdtgrp);
+ list_add_tail(&entry->node, &pcache->entries);
+ }
+ ret = asprintf(&buf, "p:%s/%s %s:0x%llx",
+ sdtgrp, note->name, pathname,
+ sdt_note__get_addr(note));
+ if (ret < 0)
+ break;
+ strlist__add(entry->tevlist, buf);
+ free(buf);
+ entry = NULL;
+ }
+ if (entry) {
+ list_del_init(&entry->node);
+ probe_cache_entry__delete(entry);
+ }
+ cleanup_sdt_note_list(&sdtlist);
+ return ret;
+}
+
static int probe_cache_entry__write(struct probe_cache_entry *entry, int fd)
{
struct str_node *snode;
struct stat st;
struct iovec iov[3];
+ const char *prefix = entry->sdt ? "%" : "#";
int ret;
/* Save stat for rollback */
ret = fstat(fd, &st);
if (ret < 0)
return ret;
- pr_debug("Writing cache: #%s\n", entry->spev);
- iov[0].iov_base = (void *)"#"; iov[0].iov_len = 1;
+ pr_debug("Writing cache: %s%s\n", prefix, entry->spev);
+ iov[0].iov_base = (void *)prefix; iov[0].iov_len = 1;
iov[1].iov_base = entry->spev; iov[1].iov_len = strlen(entry->spev);
iov[2].iov_base = (void *)"\n"; iov[2].iov_len = 1;
ret = writev(fd, iov, 3);
diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
index 0ed1fc5..ddf5ae2 100644
--- a/tools/perf/util/probe-file.h
+++ b/tools/perf/util/probe-file.h
@@ -8,6 +8,7 @@
/* Cache of probe definitions */
struct probe_cache_entry {
struct list_head node;
+ bool sdt;
struct perf_probe_event pev;
char *spev;
struct strlist *tevlist;
@@ -35,6 +36,7 @@ struct probe_cache *probe_cache__new(const char *target);
int probe_cache__add_entry(struct probe_cache *pcache,
struct perf_probe_event *pev,
struct probe_trace_event *tevs, int ntevs);
+int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname);
int probe_cache__commit(struct probe_cache *pcache);
void probe_cache__purge(struct probe_cache *pcache);
void probe_cache__delete(struct probe_cache *pcache);
next prev parent reply other threads:[~2016-06-15 3:30 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-15 3:27 [PATCH perf/core v11 00/20] perf-probe --cache and SDT support Masami Hiramatsu
2016-06-15 3:27 ` [PATCH perf/core v11 01/20] perf: util: Fix rm_rf() to handle non-regular files correctly Masami Hiramatsu
2016-06-15 3:27 ` [PATCH perf/core v11 02/20] perf-probe: Fix to add NULL check for strndup Masami Hiramatsu
2016-06-15 3:28 ` [PATCH perf/core v11 03/20] perf-buildid: Rename and export build_id_cache__cachedir() Masami Hiramatsu
2016-06-15 3:28 ` [PATCH perf/core v11 04/20] perf probe: Add perf_probe_event__copy() Masami Hiramatsu
2016-06-15 3:28 ` [PATCH perf/core v11 05/20] perf probe: Recover and export synthesize_perf_probe_point() Masami Hiramatsu
2016-06-15 3:28 ` [PATCH perf/core v11 06/20] perf probe-file: Introduce perf_cache interfaces Masami Hiramatsu
2016-06-16 8:39 ` [tip:perf/core] perf probe: " tip-bot for Masami Hiramatsu
2016-06-15 3:28 ` [PATCH perf/core v11 07/20] perf probe: Add --cache option to cache the probe definitions Masami Hiramatsu
2016-06-15 17:38 ` Arnaldo Carvalho de Melo
2016-06-15 21:38 ` Masami Hiramatsu
2016-06-16 14:29 ` Arnaldo Carvalho de Melo
2016-06-16 23:48 ` Masami Hiramatsu
2016-06-16 8:39 ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2016-06-15 3:28 ` [PATCH perf/core v11 08/20] perf probe: Use cache entry if possible Masami Hiramatsu
2016-06-15 3:29 ` [PATCH perf/core v11 09/20] perf probe: Show all cached probes Masami Hiramatsu
2016-06-15 3:29 ` [PATCH perf/core v11 10/20] perf probe: Remove caches when --cache is given Masami Hiramatsu
2016-06-15 3:29 ` [PATCH perf/core v11 11/20] perf/sdt: ELF support for SDT Masami Hiramatsu
2016-06-15 3:29 ` [PATCH perf/core v11 12/20] perf probe: Add group name support Masami Hiramatsu
2016-06-15 3:29 ` Masami Hiramatsu [this message]
2016-06-15 3:29 ` [PATCH perf/core v11 14/20] perf probe: Accept %sdt and %cached event name Masami Hiramatsu
2016-06-15 3:30 ` [PATCH perf/core v11 15/20] perf-list: Show SDT and pre-cached events Masami Hiramatsu
2016-06-15 3:30 ` [PATCH perf/core v11 16/20] perf-list: Skip SDTs placed in invalid binaries Masami Hiramatsu
2016-06-15 3:30 ` [PATCH perf/core v11 17/20] perf: probe-cache: Add for_each_probe_cache_entry() wrapper Masami Hiramatsu
2016-06-15 3:30 ` [PATCH perf/core v11 18/20] perf probe: Allow wildcard for cached events Masami Hiramatsu
2016-06-15 3:30 ` [PATCH perf/core v11 19/20] perf probe: Search SDT/cached event from all probe caches Masami Hiramatsu
2016-06-15 3:30 ` [PATCH perf/core v11 20/20] perf probe: Support @BUILDID or @FILE suffix for SDT events Masami Hiramatsu
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=20160615032943.31330.58104.stgit@devbox \
--to=mhiramat@kernel.org \
--cc=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=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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).