Instead of checking kprobe blacklist in writing phase, check it
in converting phase.

Signed-off-by: Masami Hiramatsu <[email protected]>
---
 tools/perf/util/probe-event.c |   92 ++++++++++++++++++++++++-----------------
 1 file changed, 54 insertions(+), 38 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 6c5ddb8..e8c3a25 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -549,6 +549,8 @@ static int add_module_to_probe_trace_events(struct 
probe_trace_event *tevs,
        return ret;
 }
 
+static bool kprobe_blacklist__listed(unsigned long address);
+
 /* Post processing the probe events */
 static int post_process_probe_trace_events(struct probe_trace_event *tevs,
                                           int ntevs, const char *module,
@@ -575,27 +577,32 @@ static int post_process_probe_trace_events(struct 
probe_trace_event *tevs,
        etext_addr = kernel_get_symbol_address_by_name("_etext", false);
 
        for (i = 0; i < ntevs; i++) {
-               if (tevs[i].point.address && !tevs[i].point.retprobe) {
-                       /* If we found a wrong one, mark it by NULL symbol */
-                       if (etext_addr < tevs[i].point.address) {
-                               pr_warning("%s+%lu is out of .text, skip it.\n",
-                                  tevs[i].point.symbol, tevs[i].point.offset);
-                               tmp = NULL;
-                               skipped++;
-                       } else {
-                               tmp = strdup(reloc_sym->name);
-                               if (!tmp)
-                                       return -ENOMEM;
-                       }
-                       /* If we have no realname, use symbol for it */
-                       if (!tevs[i].point.realname)
-                               tevs[i].point.realname = tevs[i].point.symbol;
-                       else
-                               free(tevs[i].point.symbol);
-                       tevs[i].point.symbol = tmp;
-                       tevs[i].point.offset = tevs[i].point.address -
-                                              reloc_sym->unrelocated_addr;
+               if (!tevs[i].point.address || tevs[i].point.retprobe)
+                       continue;
+               /* If we found a wrong one, mark it by NULL symbol */
+               if (etext_addr < tevs[i].point.address) {
+                       pr_warning("%s+%lu is out of .text, skip it.\n",
+                          tevs[i].point.symbol, tevs[i].point.offset);
+                       tmp = NULL;
+                       skipped++;
+               } else if (kprobe_blacklist__listed(tevs[i].point.address)) {
+                       pr_warning("%s is blacklisted function, skip it.\n",
+                                  tevs[i].point.symbol);
+                       tmp = NULL;
+                       skipped++;
+               } else {
+                       tmp = strdup(reloc_sym->name);
+                       if (!tmp)
+                               return -ENOMEM;
                }
+               /* If we have no realname, use symbol for it */
+               if (!tevs[i].point.realname)
+                       tevs[i].point.realname = tevs[i].point.symbol;
+               else
+                       free(tevs[i].point.symbol);
+               tevs[i].point.symbol = tmp;
+               tevs[i].point.offset = tevs[i].point.address -
+                                      reloc_sym->unrelocated_addr;
        }
        return skipped;
 }
@@ -2008,6 +2015,27 @@ kprobe_blacklist__find_by_address(struct list_head 
*blacklist,
        return NULL;
 }
 
+static LIST_HEAD(kprobe_blacklist);
+
+static void kprobe_blacklist__init(void)
+{
+       if (!list_empty(&kprobe_blacklist))
+               return;
+
+       if (kprobe_blacklist__load(&kprobe_blacklist) < 0)
+               pr_debug("No kprobe blacklist support, ignored\n");
+}
+
+static void kprobe_blacklist__release(void)
+{
+       kprobe_blacklist__delete(&kprobe_blacklist);
+}
+
+static bool kprobe_blacklist__listed(unsigned long address)
+{
+       return !!kprobe_blacklist__find_by_address(&kprobe_blacklist, address);
+}
+
 /* Show an event */
 static int show_perf_probe_event(const char *group, const char *event,
                                 struct perf_probe_event *pev,
@@ -2236,8 +2264,6 @@ static int __add_probe_trace_events(struct 
perf_probe_event *pev,
        int i, fd, ret;
        struct probe_trace_event *tev = NULL;
        struct strlist *namelist;
-       LIST_HEAD(blacklist);
-       struct kprobe_blacklist_node *node;
 
        fd = probe_file__open(PF_FL_RW | (pev->uprobes ? PF_FL_UPROBE : 0));
        if (fd < 0)
@@ -2251,27 +2277,13 @@ static int __add_probe_trace_events(struct 
perf_probe_event *pev,
                goto close_out;
        }
 
-       /* 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];
-               /* Skip if the symbol is out of .text (marked previously) */
+               /* Skip if the symbol is out of .text or blacklisted */
                if (!tev->point.symbol)
                        continue;
-               /* 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;
-               }
 
                /* Set new name for tev (and update namelist) */
                ret = probe_trace_event__set_name(tev, pev, namelist,
@@ -2305,7 +2317,6 @@ static int __add_probe_trace_events(struct 
perf_probe_event *pev,
                         tev->event);
        }
 
-       kprobe_blacklist__delete(&blacklist);
        strlist__delete(namelist);
 close_out:
        close(fd);
@@ -2513,6 +2524,9 @@ int add_perf_probe_events(struct perf_probe_event *pevs, 
int npevs)
        /* Loop 1: convert all events */
        for (i = 0; i < npevs; i++) {
                pkgs[i].pev = &pevs[i];
+               /* Init kprobe blacklist if needed */
+               if (!pkgs[i].pev->uprobes)
+                       kprobe_blacklist__init();
                /* Convert with or without debuginfo */
                ret  = convert_to_probe_trace_events(pkgs[i].pev,
                                                     &pkgs[i].tevs);
@@ -2520,6 +2534,8 @@ int add_perf_probe_events(struct perf_probe_event *pevs, 
int npevs)
                        goto end;
                pkgs[i].ntevs = ret;
        }
+       /* This just release blacklist only if allocated */
+       kprobe_blacklist__release();
 
        /* Loop 2: add all events */
        for (i = 0; i < npevs; i++) {

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to