From: Frederic Weisbecker <[email protected]>

Introducing following bits to the the perf_event_attr struct:
  - exclude_callchain_kernel to filter out kernel callchain
    from the sample dump
  - exclude_callchain_user to filter out user callchain
    from the sample dump

We need to be able to disable standard user callchain dump
when we use the dwarf cfi callchain mode, because frame
pointer based user callchains are useless in this mode.

Implementing also exclude_callchain_kernel to have complete
set of options.

Signed-off-by: Frederic Weisbecker <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Arun Sharma <[email protected]>
Cc: Benjamin Redelings <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Cyrill Gorcunov <[email protected]>
Cc: Frank Ch. Eigler <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Masami Hiramatsu <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Robert Richter <[email protected]>
Cc: Stephane Eranian <[email protected]>
Cc: Tom Zanussi <[email protected]>
Cc: Ulrich Drepper <[email protected]>
[ Added kernel callchains filtering ]
Signed-off-by: Jiri Olsa <[email protected]>
---
 include/linux/perf_event.h |  5 ++++-
 kernel/events/callchain.c  | 38 ++++++++++++++++++++++++--------------
 2 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index d1d25f6..297ca3d 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -268,7 +268,10 @@ struct perf_event_attr {
                                exclude_host   :  1, /* don't count in host   */
                                exclude_guest  :  1, /* don't count in guest  */
 
-                               __reserved_1   : 43;
+                               exclude_callchain_kernel : 1, /* exclude kernel 
callchains */
+                               exclude_callchain_user   : 1, /* exclude user 
callchains */
+
+                               __reserved_1   : 41;
 
        union {
                __u32           wakeup_events;    /* wakeup every n events */
diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c
index 98d4597..c772061 100644
--- a/kernel/events/callchain.c
+++ b/kernel/events/callchain.c
@@ -159,6 +159,11 @@ perf_callchain(struct perf_event *event, struct pt_regs 
*regs)
        int rctx;
        struct perf_callchain_entry *entry;
 
+       int kernel = !event->attr.exclude_callchain_kernel;
+       int user   = !event->attr.exclude_callchain_user;
+
+       if (!kernel && !user)
+               return NULL;
 
        entry = get_callchain_entry(&rctx);
        if (rctx == -1)
@@ -169,24 +174,29 @@ perf_callchain(struct perf_event *event, struct pt_regs 
*regs)
 
        entry->nr = 0;
 
-       if (!user_mode(regs)) {
+       if (kernel && !user_mode(regs)) {
                perf_callchain_store(entry, PERF_CONTEXT_KERNEL);
                perf_callchain_kernel(entry, regs);
-               if (current->mm)
-                       regs = task_pt_regs(current);
-               else
-                       regs = NULL;
        }
 
-       if (regs) {
-               /*
-                * Disallow cross-task user callchains.
-                */
-               if (event->ctx->task && event->ctx->task != current)
-                       goto exit_put;
-
-               perf_callchain_store(entry, PERF_CONTEXT_USER);
-               perf_callchain_user(entry, regs);
+       if (user) {
+               if (!user_mode(regs)) {
+                       if  (current->mm)
+                               regs = task_pt_regs(current);
+                       else
+                               regs = NULL;
+               }
+
+               if (regs) {
+                       /*
+                        * Disallow cross-task user callchains.
+                        */
+                       if (event->ctx->task && event->ctx->task != current)
+                               goto exit_put;
+
+                       perf_callchain_store(entry, PERF_CONTEXT_USER);
+                       perf_callchain_user(entry, regs);
+               }
        }
 
 exit_put:
-- 
1.7.11.2

--
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