[PATCH 5/7] perf: Make perf_fetch_caller_regs rewind to the first caller only

From: Frederic Weisbecker
Date: Thu Mar 25 2010 - 21:53:32 EST


Trace events now only need to rewind the regs to the immediate
caller, so we don't need anymore to implement the support for
further stack walking.

Signed-off-by: Frederic Weisbecker <fweisbec@xxxxxxxxx>
Cc: Peter Zijlstra <a.p.zijlstra@xxxxxxxxx>
Cc: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
Cc: Paul Mackerras <paulus@xxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxx>
Cc: David Miller <davem@xxxxxxxxxxxxx>
Cc: Archs <linux-arch@xxxxxxxxxxxxxxx>
---
arch/x86/include/asm/perf_event.h | 6 +++---
arch/x86/include/asm/stacktrace.h | 5 ++---
include/linux/perf_event.h | 30 +++++-------------------------
include/trace/ftrace.h | 2 +-
4 files changed, 11 insertions(+), 32 deletions(-)

diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 4bf3d37..1df2317 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -157,9 +157,9 @@ extern void perf_events_lapic_init(void);

#include <asm/stacktrace.h>

-#define perf_arch_fetch_caller_regs(regs, ip, skip) \
- (regs)->ip = ip; \
- (regs)->bp = rewind_frame_pointer(skip); \
+#define perf_arch_fetch_caller_regs(regs, __ip) \
+ (regs)->ip = __ip; \
+ (regs)->bp = caller_frame_pointer(); \
(regs)->cs = __KERNEL_CS; \
local_save_flags((regs)->flags);

diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h
index 8fb70b7..62c9897 100644
--- a/arch/x86/include/asm/stacktrace.h
+++ b/arch/x86/include/asm/stacktrace.h
@@ -74,15 +74,14 @@ struct stack_frame {
unsigned long return_address;
};

-static inline unsigned long rewind_frame_pointer(int n)
+static inline unsigned long caller_frame_pointer(void)
{
struct stack_frame *frame;

get_bp(frame);

#ifdef CONFIG_FRAME_POINTER
- while (n--)
- frame = frame->next_frame;
+ frame = frame->next_frame;
#endif

return (unsigned long)frame;
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 76b680f..3b59cf7 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -869,42 +869,22 @@ perf_sw_event(u32 event_id, u64 nr, int nmi, struct pt_regs *regs, u64 addr)

#ifndef perf_arch_fetch_caller_regs
static inline void
-perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip){ }
+perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip) { }
#endif

/*
- * Take a snapshot of the regs. Skip ip and frame pointer to
- * the nth caller. We only need a few of the regs:
+ * Take a snapshot of the regs. Rewind ip and frame pointer to
+ * the caller. We only need a few of the regs:
* - ip for PERF_SAMPLE_IP
* - cs for user_mode() tests
* - bp for callchains
* - eflags, for future purposes, just in case
*/
-static inline void perf_fetch_caller_regs(struct pt_regs *regs, int skip)
+static inline void perf_fetch_caller_regs(struct pt_regs *regs)
{
- unsigned long ip;
-
memset(regs, 0, sizeof(*regs));

- switch (skip) {
- case 1 :
- ip = CALLER_ADDR0;
- break;
- case 2 :
- ip = CALLER_ADDR1;
- break;
- case 3 :
- ip = CALLER_ADDR2;
- break;
- case 4:
- ip = CALLER_ADDR3;
- break;
- /* No need to support further for now */
- default:
- ip = 0;
- }
-
- perf_arch_fetch_caller_regs(regs, ip, skip);
+ perf_arch_fetch_caller_regs(regs, CALLER_ADDR0);
}

extern void __perf_event_mmap(struct vm_area_struct *vma);
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index 882c648..82e9977 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -795,7 +795,7 @@ static notrace void perf_trace_##call(proto) \
struct ftrace_event_call *event_call = &event_##call; \
struct pt_regs *__regs = &get_cpu_var(perf_trace_regs); \
\
- perf_fetch_caller_regs(__regs, 1); \
+ perf_fetch_caller_regs(__regs); \
\
perf_trace_templ_##template(event_call, __regs, args); \
\
--
1.6.2.3

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