Commit d350bd57 authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Arnaldo Carvalho de Melo

perf probe: Show usage even if the last event is skipped

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: default avatarMasami 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.localdomainSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 5d618324
...@@ -2157,7 +2157,8 @@ static bool kprobe_blacklist__listed(unsigned long address) ...@@ -2157,7 +2157,8 @@ static bool kprobe_blacklist__listed(unsigned long address)
return !!kprobe_blacklist__find_by_address(&kprobe_blacklist, 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, const char *module,
struct strbuf *result) struct strbuf *result)
{ {
...@@ -2170,7 +2171,7 @@ static int perf_probe_event__sprintf(struct perf_probe_event *pev, ...@@ -2170,7 +2171,7 @@ static int perf_probe_event__sprintf(struct perf_probe_event *pev,
if (!place) if (!place)
return -EINVAL; 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) if (ret < 0)
goto out; goto out;
...@@ -2195,13 +2196,14 @@ static int perf_probe_event__sprintf(struct perf_probe_event *pev, ...@@ -2195,13 +2196,14 @@ static int perf_probe_event__sprintf(struct perf_probe_event *pev,
} }
/* Show an event */ /* 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) const char *module, bool use_stdout)
{ {
struct strbuf buf = STRBUF_INIT; struct strbuf buf = STRBUF_INIT;
int ret; int ret;
ret = perf_probe_event__sprintf(pev, module, &buf); ret = perf_probe_event__sprintf(group, event, pev, module, &buf);
if (ret >= 0) { if (ret >= 0) {
if (use_stdout) if (use_stdout)
printf("%s\n", buf.buf); printf("%s\n", buf.buf);
...@@ -2253,7 +2255,8 @@ static int __show_perf_probe_events(int fd, bool is_kprobe, ...@@ -2253,7 +2255,8 @@ static int __show_perf_probe_events(int fd, bool is_kprobe,
is_kprobe); is_kprobe);
if (ret < 0) if (ret < 0)
goto next; 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); true);
} }
next: next:
...@@ -2438,7 +2441,7 @@ static int __add_probe_trace_events(struct perf_probe_event *pev, ...@@ -2438,7 +2441,7 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
int i, fd, ret; int i, fd, ret;
struct probe_trace_event *tev = NULL; struct probe_trace_event *tev = NULL;
char buf[64]; char buf[64];
const char *event, *group; const char *event = NULL, *group = NULL;
struct strlist *namelist; struct strlist *namelist;
bool safename; bool safename;
...@@ -2500,15 +2503,12 @@ static int __add_probe_trace_events(struct perf_probe_event *pev, ...@@ -2500,15 +2503,12 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
/* Add added event name to namelist */ /* Add added event name to namelist */
strlist__add(namelist, event); strlist__add(namelist, event);
/* Trick here - save current event/group */ /* We use tev's name for showing new events */
event = pev->event; show_perf_probe_event(tev->group, tev->event, pev,
group = pev->group; tev->point.module, false);
pev->event = tev->event; /* Save the last valid name */
pev->group = tev->group; event = tev->event;
show_perf_probe_event(pev, tev->point.module, false); group = tev->group;
/* Trick here - restore current event/group */
pev->event = (char *)event;
pev->group = (char *)group;
/* /*
* Probes after the first probe which comes from same * Probes after the first probe which comes from same
...@@ -2522,11 +2522,10 @@ static int __add_probe_trace_events(struct perf_probe_event *pev, ...@@ -2522,11 +2522,10 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
warn_uprobe_event_compat(tev); warn_uprobe_event_compat(tev);
/* Note that it is possible to skip all events because of blacklist */ /* 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. */ /* Show how to use the event. */
pr_info("\nYou can now use it in all perf tools, such as:\n\n"); 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, pr_info("\tperf record -e %s:%s -aR sleep 1\n\n", group, event);
tev->event);
} }
strlist__delete(namelist); strlist__delete(namelist);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment