perf probe: Support SDT markers having reference counter (semaphore)

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: 0x0000000010020036

  # ./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

Link: http://lkml.kernel.org/r/20180820044250.11659-5-ravi.bangoria@linux.ibm.com

Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Reviewed-by: Song Liu <songliubraving@fb.com>
Tested-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
This commit is contained in:
Ravi Bangoria
2018-08-20 10:12:50 +05:30
committed by Steven Rostedt (VMware)
parent ccea8727dc
commit 5a5e3d3cea
6 changed files with 106 additions and 22 deletions

View File

@@ -696,8 +696,16 @@ out_err:
#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]
: (unsigned long long)note->addr.a64[0];
return note->bit32 ?
(unsigned long long)note->addr.a32[SDT_NOTE_IDX_LOC] :
(unsigned long long)note->addr.a64[SDT_NOTE_IDX_LOC];
}
static unsigned long long sdt_note__get_ref_ctr_offset(struct sdt_note *note)
{
return note->bit32 ?
(unsigned long long)note->addr.a32[SDT_NOTE_IDX_REFCTR] :
(unsigned long long)note->addr.a64[SDT_NOTE_IDX_REFCTR];
}
static const char * const type_to_suffix[] = {
@@ -775,14 +783,21 @@ static char *synthesize_sdt_probe_command(struct sdt_note *note,
{
struct strbuf buf;
char *ret = NULL, **args;
int i, args_count;
int i, args_count, err;
unsigned long long ref_ctr_offset;
if (strbuf_init(&buf, 32) < 0)
return NULL;
if (strbuf_addf(&buf, "p:%s/%s %s:0x%llx",
sdtgrp, note->name, pathname,
sdt_note__get_addr(note)) < 0)
err = strbuf_addf(&buf, "p:%s/%s %s:0x%llx",
sdtgrp, note->name, pathname,
sdt_note__get_addr(note));
ref_ctr_offset = sdt_note__get_ref_ctr_offset(note);
if (ref_ctr_offset && err >= 0)
err = strbuf_addf(&buf, "(0x%llx)", ref_ctr_offset);
if (err < 0)
goto error;
if (!note->args)
@@ -998,6 +1013,7 @@ int probe_cache__show_all_caches(struct strfilter *filter)
enum ftrace_readme {
FTRACE_README_PROBE_TYPE_X = 0,
FTRACE_README_KRETPROBE_OFFSET,
FTRACE_README_UPROBE_REF_CTR,
FTRACE_README_END,
};
@@ -1009,6 +1025,7 @@ static struct {
[idx] = {.pattern = pat, .avail = false}
DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"),
DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"),
DEFINE_TYPE(FTRACE_README_UPROBE_REF_CTR, "*ref_ctr_offset*"),
};
static bool scan_ftrace_readme(enum ftrace_readme type)
@@ -1064,3 +1081,8 @@ bool kretprobe_offset_is_supported(void)
{
return scan_ftrace_readme(FTRACE_README_KRETPROBE_OFFSET);
}
bool uprobe_ref_ctr_is_supported(void)
{
return scan_ftrace_readme(FTRACE_README_UPROBE_REF_CTR);
}