[PATCH v3 9/9] perf probe: Support SDT markers having reference counter (semaphore)
From: Ravi Bangoria With this, perf buildid-cache will save SDT markers with reference counter in probe cache. Perf probe will be able to probe markers having reference counter. Ex, # readelf -n /tmp/tick | grep -A1 loop2 Name: loop2 ... Semaphore: 0x10020036 # ./perf buildid-cache --add /tmp/tick # ./perf probe sdt_tick:loop2 # ./perf stat -e sdt_tick:loop2 /tmp/tick hi: 0 hi: 1 hi: 2 ^C Performance counter stats for '/tmp/tick': 3 sdt_tick:loop2 2.561851452 seconds time elapsed Signed-off-by: Ravi Bangoria --- tools/perf/util/probe-event.c | 39 tools/perf/util/probe-event.h | 1 + tools/perf/util/probe-file.c | 34 ++-- tools/perf/util/probe-file.h | 1 + tools/perf/util/symbol-elf.c | 46 --- tools/perf/util/symbol.h | 7 +++ 6 files changed, 106 insertions(+), 22 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index e1dbc98..9b9c26e 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -1832,6 +1832,12 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev) tp->offset = strtoul(fmt2_str, NULL, 10); } + if (tev->uprobes) { + fmt2_str = strchr(p, '('); + if (fmt2_str) + tp->ref_ctr_offset = strtoul(fmt2_str + 1, NULL, 0); + } + tev->nargs = argc - 2; tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); if (tev->args == NULL) { @@ -2025,6 +2031,22 @@ static int synthesize_probe_trace_arg(struct probe_trace_arg *arg, return err; } +static int +synthesize_uprobe_trace_def(struct probe_trace_event *tev, struct strbuf *buf) +{ + struct probe_trace_point *tp = &tev->point; + int err; + + err = strbuf_addf(buf, "%s:0x%lx", tp->module, tp->address); + + if (err >= 0 && tp->ref_ctr_offset) { + if (!uprobe_ref_ctr_is_supported()) + return -1; + err = strbuf_addf(buf, "(0x%lx)", tp->ref_ctr_offset); + } + return err >= 0 ? 0 : -1; +} + char *synthesize_probe_trace_command(struct probe_trace_event *tev) { struct probe_trace_point *tp = &tev->point; @@ -2054,15 +2076,17 @@ char *synthesize_probe_trace_command(struct probe_trace_event *tev) } /* Use the tp->address for uprobes */ - if (tev->uprobes) - err = strbuf_addf(&buf, "%s:0x%lx", tp->module, tp->address); - else if (!strncmp(tp->symbol, "0x", 2)) + if (tev->uprobes) { + err = synthesize_uprobe_trace_def(tev, &buf); + } else if (!strncmp(tp->symbol, "0x", 2)) { /* Absolute address. See try_to_find_absolute_address() */ err = strbuf_addf(&buf, "%s%s0x%lx", tp->module ?: "", tp->module ? ":" : "", tp->address); - else + } else { err = strbuf_addf(&buf, "%s%s%s+%lu", tp->module ?: "", tp->module ? ":" : "", tp->symbol, tp->offset); + } + if (err) goto error; @@ -2646,6 +2670,13 @@ static void warn_uprobe_event_compat(struct probe_trace_event *tev) { int i; char *buf = synthesize_probe_trace_command(tev); + struct probe_trace_point *tp = &tev->point; + + if (tp->ref_ctr_offset && !uprobe_ref_ctr_is_supported()) { + pr_warning("A semaphore is associated with %s:%s and " + "seems your kernel doesn't support it.\n", + tev->group, tev->event); + } /* Old uprobe event doesn't support memory dereference */ if (!tev->uprobes || tev->nargs == 0 || !buf) diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index 45b14f0..15a98c3 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h @@ -27,6 +27,7 @@ struct probe_trace_point { char*symbol;/* Base symbol */ char*module;/* Module name */ unsigned long offset; /* Offset from symbol */ + unsigned long ref_ctr_offset; /* SDT reference counter offset */ unsigned long address;/* Actual address of the trace point */ boolretprobe; /* Return probe flag */ }; diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index 4ae1123..a17ba6a 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -697,8 +697,16 @@ int probe_cache__add_entry(struct probe_cache *pcache, #ifdef HAVE_GELF_GETNOTE_SUPPORT static unsigned long long sdt_note__get_addr(struct sdt_note *note) { - return note->bit32 ? (unsigned long long)note->addr.a32[0] -: (unsign
Re: [PATCH v3 9/9] perf probe: Support SDT markers having reference counter (semaphore)
On Tue, 17 Apr 2018 10:02:44 +0530 Ravi Bangoria wrote: > From: Ravi Bangoria > > With this, perf buildid-cache will save SDT markers with reference > counter in probe cache. Perf probe will be able to probe markers > having reference counter. Ex, > > # readelf -n /tmp/tick | grep -A1 loop2 > Name: loop2 > ... Semaphore: 0x10020036 > > # ./perf buildid-cache --add /tmp/tick > # ./perf probe sdt_tick:loop2 > # ./perf stat -e sdt_tick:loop2 /tmp/tick > hi: 0 > hi: 1 > hi: 2 > ^C > Performance counter stats for '/tmp/tick': > 3 sdt_tick:loop2 >2.561851452 seconds time elapsed > > Signed-off-by: Ravi Bangoria Looks good to me. Acked-by: Masami Hiramatsu Thanks! > --- > tools/perf/util/probe-event.c | 39 > tools/perf/util/probe-event.h | 1 + > tools/perf/util/probe-file.c | 34 ++-- > tools/perf/util/probe-file.h | 1 + > tools/perf/util/symbol-elf.c | 46 > --- > tools/perf/util/symbol.h | 7 +++ > 6 files changed, 106 insertions(+), 22 deletions(-) > > diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c > index e1dbc98..9b9c26e 100644 > --- a/tools/perf/util/probe-event.c > +++ b/tools/perf/util/probe-event.c > @@ -1832,6 +1832,12 @@ int parse_probe_trace_command(const char *cmd, struct > probe_trace_event *tev) > tp->offset = strtoul(fmt2_str, NULL, 10); > } > > + if (tev->uprobes) { > + fmt2_str = strchr(p, '('); > + if (fmt2_str) > + tp->ref_ctr_offset = strtoul(fmt2_str + 1, NULL, 0); > + } > + > tev->nargs = argc - 2; > tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); > if (tev->args == NULL) { > @@ -2025,6 +2031,22 @@ static int synthesize_probe_trace_arg(struct > probe_trace_arg *arg, > return err; > } > > +static int > +synthesize_uprobe_trace_def(struct probe_trace_event *tev, struct strbuf > *buf) > +{ > + struct probe_trace_point *tp = &tev->point; > + int err; > + > + err = strbuf_addf(buf, "%s:0x%lx", tp->module, tp->address); > + > + if (err >= 0 && tp->ref_ctr_offset) { > + if (!uprobe_ref_ctr_is_supported()) > + return -1; > + err = strbuf_addf(buf, "(0x%lx)", tp->ref_ctr_offset); > + } > + return err >= 0 ? 0 : -1; > +} > + > char *synthesize_probe_trace_command(struct probe_trace_event *tev) > { > struct probe_trace_point *tp = &tev->point; > @@ -2054,15 +2076,17 @@ char *synthesize_probe_trace_command(struct > probe_trace_event *tev) > } > > /* Use the tp->address for uprobes */ > - if (tev->uprobes) > - err = strbuf_addf(&buf, "%s:0x%lx", tp->module, tp->address); > - else if (!strncmp(tp->symbol, "0x", 2)) > + if (tev->uprobes) { > + err = synthesize_uprobe_trace_def(tev, &buf); > + } else if (!strncmp(tp->symbol, "0x", 2)) { > /* Absolute address. See try_to_find_absolute_address() */ > err = strbuf_addf(&buf, "%s%s0x%lx", tp->module ?: "", > tp->module ? ":" : "", tp->address); > - else > + } else { > err = strbuf_addf(&buf, "%s%s%s+%lu", tp->module ?: "", > tp->module ? ":" : "", tp->symbol, tp->offset); > + } > + > if (err) > goto error; > > @@ -2646,6 +2670,13 @@ static void warn_uprobe_event_compat(struct > probe_trace_event *tev) > { > int i; > char *buf = synthesize_probe_trace_command(tev); > + struct probe_trace_point *tp = &tev->point; > + > + if (tp->ref_ctr_offset && !uprobe_ref_ctr_is_supported()) { > + pr_warning("A semaphore is associated with %s:%s and " > +"seems your kernel doesn't support it.\n", > +tev->group, tev->event); > + } > > /* Old uprobe event doesn't support memory dereference */ > if (!tev->uprobes || tev->nargs == 0 || !buf) > diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h > index 45b14f0..15a98c3 100644 > --- a/tools/perf/util/probe-event.h > +++ b/tools/perf/util/probe-event.h > @@ -27,6 +27,7 @@ struct probe_trace_point { > char*symbol;/* Base symbol */ > char*module;/* Module name */ > unsigned long offset; /* Offset from symbol */ > + unsigned long ref_ctr_offset; /* SDT reference counter offset */ > unsigned long address;/* Actual address of the trace point */ > boolretprobe; /* Return probe flag */ > }; > diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c > index 4ae1123..a17ba6a 100644 > --- a/tools/perf/util/probe-file.c > +++ b/tools/perf/util/probe-file.c > @@ -697