Skip to content

Commit

Permalink
perf probe: Show usage even if the last event is skipped
Browse files Browse the repository at this point in the history
When the last part of converted events are blacklisted or out-of-text,
those are skipped and perf probe doesn't show usage examples.  This
fixes it to show the example even if the last part of event list is
skipped.

E.g. without this patch, events are added, but suddenly end:

  # perf probe vfs_*
  vfs_caches_init_early is out of .text, skip it.
  vfs_caches_init is out of .text, skip it.
  Added new events:
    probe:vfs_fallocate  (on vfs_*)
    probe:vfs_open       (on vfs_*)
  ...
    probe:vfs_dentry_acceptable (on vfs_*)
    probe:vfs_load_quota_inode (on vfs_*)
  #

With this fix:

  # perf probe vfs_*
  vfs_caches_init_early is out of .text, skip it.
  vfs_caches_init is out of .text, skip it.
  Added new events:
    probe:vfs_fallocate  (on vfs_*)
  ...
    probe:vfs_load_quota_inode (on vfs_*)

  You can now use it in all perf tools, such as:

	perf record -e probe:vfs_load_quota_inode -aR sleep 1

Note that this can be reproduced ONLY IF the vfs_caches_init* is the
last part of matched symbol list. I've checked this happens on
"3.19.0-generic #18-Ubuntu" kernel binary.

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Naohiro Aota <naota@elisp.net>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20150616115057.19906.5502.stgit@localhost.localdomain
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
mhiramathitachi authored and acmel committed Jun 17, 2015
1 parent 5d61832 commit d350bd5
Showing 1 changed file with 17 additions and 18 deletions.
35 changes: 17 additions & 18 deletions tools/perf/util/probe-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -2157,7 +2157,8 @@ static bool kprobe_blacklist__listed(unsigned long address)
return !!kprobe_blacklist__find_by_address(&kprobe_blacklist, address);
}

static int perf_probe_event__sprintf(struct perf_probe_event *pev,
static int perf_probe_event__sprintf(const char *group, const char *event,
struct perf_probe_event *pev,
const char *module,
struct strbuf *result)
{
Expand All @@ -2170,7 +2171,7 @@ static int perf_probe_event__sprintf(struct perf_probe_event *pev,
if (!place)
return -EINVAL;

ret = e_snprintf(buf, 128, "%s:%s", pev->group, pev->event);
ret = e_snprintf(buf, 128, "%s:%s", group, event);
if (ret < 0)
goto out;

Expand All @@ -2195,13 +2196,14 @@ static int perf_probe_event__sprintf(struct perf_probe_event *pev,
}

/* Show an event */
static int show_perf_probe_event(struct perf_probe_event *pev,
static int show_perf_probe_event(const char *group, const char *event,
struct perf_probe_event *pev,
const char *module, bool use_stdout)
{
struct strbuf buf = STRBUF_INIT;
int ret;

ret = perf_probe_event__sprintf(pev, module, &buf);
ret = perf_probe_event__sprintf(group, event, pev, module, &buf);
if (ret >= 0) {
if (use_stdout)
printf("%s\n", buf.buf);
Expand Down Expand Up @@ -2253,7 +2255,8 @@ static int __show_perf_probe_events(int fd, bool is_kprobe,
is_kprobe);
if (ret < 0)
goto next;
ret = show_perf_probe_event(&pev, tev.point.module,
ret = show_perf_probe_event(pev.group, pev.event,
&pev, tev.point.module,
true);
}
next:
Expand Down Expand Up @@ -2438,7 +2441,7 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
int i, fd, ret;
struct probe_trace_event *tev = NULL;
char buf[64];
const char *event, *group;
const char *event = NULL, *group = NULL;
struct strlist *namelist;
bool safename;

Expand Down Expand Up @@ -2500,15 +2503,12 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
/* Add added event name to namelist */
strlist__add(namelist, event);

/* Trick here - save current event/group */
event = pev->event;
group = pev->group;
pev->event = tev->event;
pev->group = tev->group;
show_perf_probe_event(pev, tev->point.module, false);
/* Trick here - restore current event/group */
pev->event = (char *)event;
pev->group = (char *)group;
/* We use tev's name for showing new events */
show_perf_probe_event(tev->group, tev->event, pev,
tev->point.module, false);
/* Save the last valid name */
event = tev->event;
group = tev->group;

/*
* Probes after the first probe which comes from same
Expand All @@ -2522,11 +2522,10 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
warn_uprobe_event_compat(tev);

/* Note that it is possible to skip all events because of blacklist */
if (ret >= 0 && tev->event) {
if (ret >= 0 && event) {
/* Show how to use the event. */
pr_info("\nYou can now use it in all perf tools, such as:\n\n");
pr_info("\tperf record -e %s:%s -aR sleep 1\n\n", tev->group,
tev->event);
pr_info("\tperf record -e %s:%s -aR sleep 1\n\n", group, event);
}

strlist__delete(namelist);
Expand Down

0 comments on commit d350bd5

Please sign in to comment.