From: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
To: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>,
namhyung@kernel.org, Ingo Molnar <mingo@kernel.org>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: [PATCH perf/core ] perf-probe: Check kprobes blacklist when adding new events
Date: Thu, 19 Feb 2015 23:31:13 +0900 [thread overview]
Message-ID: <20150219143113.14434.5387.stgit@localhost.localdomain> (raw)
In-Reply-To: <20150211204220.GM24251@kernel.org>
Recent linux kernel provides a blacklist of the functions which
can not be probed. perf probe can now check this blacklist before
setting new events and indicate better error message for users.
Without this patch,
----
# perf probe --add vmalloc_fault
Added new event:
Failed to write event: Invalid argument
Error: Failed to add events.
----
With this patch
----
# perf probe --add vmalloc_fault
Added new event:
Warning: Skipped probing on blacklisted function: vmalloc_fault
----
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reported-by: Arnaldo Carvalho de Melo <acme@kernel.org>
---
tools/perf/util/probe-event.c | 109 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 108 insertions(+), 1 deletion(-)
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 9dfbed9..662d454 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1903,6 +1903,95 @@ static struct strlist *get_probe_trace_command_rawlist(int fd)
return sl;
}
+struct kprobe_blacklist_node {
+ struct list_head list;
+ unsigned long start;
+ unsigned long end;
+ char *symbol;
+};
+
+static void kprobe_blacklist__delete(struct list_head *blacklist)
+{
+ struct kprobe_blacklist_node *node;
+
+ while (!list_empty(blacklist)) {
+ node = list_first_entry(blacklist,
+ struct kprobe_blacklist_node, list);
+ list_del(&node->list);
+ free(node->symbol);
+ free(node);
+ }
+}
+
+static int kprobe_blacklist__load(struct list_head *blacklist)
+{
+ struct kprobe_blacklist_node *node;
+ const char *__debugfs = debugfs_find_mountpoint();
+ char buf[PATH_MAX], *p;
+ FILE *fp;
+ int ret;
+
+ if (__debugfs == NULL)
+ return -ENOTSUP;
+
+ ret = e_snprintf(buf, PATH_MAX, "%s/kprobes/blacklist", __debugfs);
+ if (ret < 0)
+ return ret;
+
+ fp = fopen(buf, "r");
+ if (!fp)
+ return -errno;
+
+ ret = 0;
+ while (fgets(buf, PATH_MAX, fp)) {
+ node = zalloc(sizeof(*node));
+ if (!node) {
+ ret = -ENOMEM;
+ break;
+ }
+ INIT_LIST_HEAD(&node->list);
+ list_add_tail(&node->list, blacklist);
+ if (sscanf(buf, "0x%lx-0x%lx", &node->start, &node->end) != 2) {
+ ret = -EINVAL;
+ break;
+ }
+ p = strchr(buf, '\t');
+ if (p) {
+ p++;
+ if (p[strlen(p) - 1] == '\n')
+ p[strlen(p) - 1] = '\0';
+ } else
+ p = (char *)"unknown";
+ node->symbol = strdup(p);
+ if (!node->symbol) {
+ ret = -ENOMEM;
+ break;
+ }
+ pr_debug2("Blacklist: 0x%lx-0x%lx, %s\n",
+ node->start, node->end, node->symbol);
+ ret++;
+ }
+ if (ret < 0)
+ kprobe_blacklist__delete(blacklist);
+ fclose(fp);
+
+ return ret;
+}
+
+static struct kprobe_blacklist_node *
+kprobe_blacklist__find_by_address(struct list_head *blacklist,
+ unsigned long address)
+{
+ struct kprobe_blacklist_node *node;
+
+ list_for_each_entry(node, blacklist, list) {
+ if (node->start <= address && address <= node->end)
+ return node;
+ }
+
+ return NULL;
+}
+
/* Show an event */
static int show_perf_probe_event(struct perf_probe_event *pev,
const char *module)
@@ -2117,6 +2206,8 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
char buf[64];
const char *event, *group;
struct strlist *namelist;
+ LIST_HEAD(blacklist);
+ struct kprobe_blacklist_node *node;
if (pev->uprobes)
fd = open_uprobe_events(true);
@@ -2134,11 +2225,25 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
pr_debug("Failed to get current event list.\n");
return -EIO;
}
+ /* Get kprobe blacklist if exists */
+ if (!pev->uprobes) {
+ ret = kprobe_blacklist__load(&blacklist);
+ if (ret < 0)
+ pr_debug("No kprobe blacklist support, ignored\n");
+ }
ret = 0;
pr_info("Added new event%s\n", (ntevs > 1) ? "s:" : ":");
for (i = 0; i < ntevs; i++) {
tev = &tevs[i];
+ /* Ensure that the address is NOT blacklisted */
+ node = kprobe_blacklist__find_by_address(&blacklist,
+ tev->point.address);
+ if (node) {
+ pr_warning("Warning: Skipped probing on blacklisted function: %s\n", node->symbol);
+ continue;
+ }
+
if (pev->event)
event = pev->event;
else
@@ -2189,13 +2294,15 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
allow_suffix = true;
}
- if (ret >= 0) {
+ /* Note that it is possible to skip all events because of blacklist */
+ if (ret >= 0 && tev->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);
}
+ kprobe_blacklist__delete(&blacklist);
strlist__delete(namelist);
close(fd);
return ret;
next prev parent reply other threads:[~2015-02-19 14:31 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-30 9:37 [PATCH perf/core 0/2] perf-probe: bugfix and update Masami Hiramatsu
2015-01-30 9:37 ` [PATCH perf/core 1/2] [BUGFIX] perf-probe: Fix to handle optimized not-inlined but has no instance Masami Hiramatsu
2015-01-30 14:21 ` Arnaldo Carvalho de Melo
2015-01-30 14:32 ` Arnaldo Carvalho de Melo
2015-02-02 8:41 ` Masami Hiramatsu
2015-02-08 8:37 ` Masami Hiramatsu
2015-02-11 20:42 ` Arnaldo Carvalho de Melo
2015-02-19 14:31 ` Masami Hiramatsu [this message]
2015-02-25 21:50 ` [PATCH perf/core ] perf-probe: Check kprobes blacklist when adding new events Arnaldo Carvalho de Melo
2015-02-28 9:30 ` [tip:perf/core] perf probe: " tip-bot for Masami Hiramatsu
2015-02-18 18:25 ` [tip:perf/core] perf probe: Fix to handle optimized not-inlined functions tip-bot for Masami Hiramatsu
2015-01-30 9:37 ` [PATCH perf/core 2/2] [DOC] perf-probe: Update perf-probe document Masami Hiramatsu
2015-02-18 18:25 ` [tip:perf/core] perf probe: Update man page tip-bot for 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=20150219143113.14434.5387.stgit@localhost.localdomain \
--to=masami.hiramatsu.pt@hitachi.com \
--cc=acme@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.