[PATCH 07/17] perf: Add attribute to filter out callchains

2012-07-22 Thread Jiri Olsa
From: Frederic Weisbecker 

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 
[ Added kernel callchains filtering ]
Signed-off-by: Jiri Olsa 
---
 include/linux/perf_event.h |5 -
 kernel/events/callchain.c  |   25 +++--
 kernel/events/core.c   |5 -
 kernel/events/internal.h   |3 ++-
 4 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index b4663b3..91c2de2 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -259,7 +259,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 6581a04..905ffb2 100644
--- a/kernel/events/callchain.c
+++ b/kernel/events/callchain.c
@@ -153,12 +153,12 @@ put_callchain_entry(int rctx)
put_recursion_context(__get_cpu_var(callchain_recursion), rctx);
 }
 
-struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
+struct perf_callchain_entry *perf_callchain(struct pt_regs *regs,
+   int kernel, int user)
 {
int rctx;
struct perf_callchain_entry *entry;
 
-
entry = get_callchain_entry();
if (rctx == -1)
return NULL;
@@ -168,18 +168,23 @@ struct perf_callchain_entry *perf_callchain(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) {
-   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) {
+   perf_callchain_store(entry, PERF_CONTEXT_USER);
+   perf_callchain_user(entry, regs);
+   }
}
 
 exit_put:
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 8a9cf80..78f405e 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -4126,8 +4126,11 @@ void perf_prepare_sample(struct perf_event_header 
*header,
 
if (sample_type & PERF_SAMPLE_CALLCHAIN) {
int size = 1;
+   int kernel = !event->attr.exclude_callchain_kernel;
+   int user   = !event->attr.exclude_callchain_user;
 
-   data->callchain = perf_callchain(regs);
+   if (kernel || user)
+   data->callchain = perf_callchain(regs, kernel, user);
 
if (data->callchain)
size += data->callchain->nr;
diff --git a/kernel/events/internal.h b/kernel/events/internal.h
index be1ef29..abcc03d 100644
--- a/kernel/events/internal.h
+++ b/kernel/events/internal.h
@@ -125,7 +125,8 @@ DEFINE_OUTPUT_COPY(__output_skip, MEMCPY_SKIP)
 DEFINE_OUTPUT_COPY(__output_copy_user, arch_perf_out_copy_user)
 
 /* Callchain handling */
-extern struct perf_callchain_entry *perf_callchain(struct pt_regs *regs);
+extern struct perf_callchain_entry *perf_callchain(struct pt_regs *regs,
+  int kernel, int user);
 extern int get_callchain_buffers(void);
 extern void put_callchain_buffers(void);
 
-- 
1.7.7.6

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


[PATCH 07/17] perf: Add attribute to filter out callchains

2012-07-22 Thread Jiri Olsa
From: Frederic Weisbecker fweis...@gmail.com

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 fweis...@gmail.com
[ Added kernel callchains filtering ]
Signed-off-by: Jiri Olsa jo...@redhat.com
---
 include/linux/perf_event.h |5 -
 kernel/events/callchain.c  |   25 +++--
 kernel/events/core.c   |5 -
 kernel/events/internal.h   |3 ++-
 4 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index b4663b3..91c2de2 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -259,7 +259,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 6581a04..905ffb2 100644
--- a/kernel/events/callchain.c
+++ b/kernel/events/callchain.c
@@ -153,12 +153,12 @@ put_callchain_entry(int rctx)
put_recursion_context(__get_cpu_var(callchain_recursion), rctx);
 }
 
-struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
+struct perf_callchain_entry *perf_callchain(struct pt_regs *regs,
+   int kernel, int user)
 {
int rctx;
struct perf_callchain_entry *entry;
 
-
entry = get_callchain_entry(rctx);
if (rctx == -1)
return NULL;
@@ -168,18 +168,23 @@ struct perf_callchain_entry *perf_callchain(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) {
-   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) {
+   perf_callchain_store(entry, PERF_CONTEXT_USER);
+   perf_callchain_user(entry, regs);
+   }
}
 
 exit_put:
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 8a9cf80..78f405e 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -4126,8 +4126,11 @@ void perf_prepare_sample(struct perf_event_header 
*header,
 
if (sample_type  PERF_SAMPLE_CALLCHAIN) {
int size = 1;
+   int kernel = !event-attr.exclude_callchain_kernel;
+   int user   = !event-attr.exclude_callchain_user;
 
-   data-callchain = perf_callchain(regs);
+   if (kernel || user)
+   data-callchain = perf_callchain(regs, kernel, user);
 
if (data-callchain)
size += data-callchain-nr;
diff --git a/kernel/events/internal.h b/kernel/events/internal.h
index be1ef29..abcc03d 100644
--- a/kernel/events/internal.h
+++ b/kernel/events/internal.h
@@ -125,7 +125,8 @@ DEFINE_OUTPUT_COPY(__output_skip, MEMCPY_SKIP)
 DEFINE_OUTPUT_COPY(__output_copy_user, arch_perf_out_copy_user)
 
 /* Callchain handling */
-extern struct perf_callchain_entry *perf_callchain(struct pt_regs *regs);
+extern struct perf_callchain_entry *perf_callchain(struct pt_regs *regs,
+  int kernel, int user);
 extern int get_callchain_buffers(void);
 extern void put_callchain_buffers(void);
 
-- 
1.7.7.6

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