diff options
| author | Frederic Weisbecker <fweisbec@gmail.com> | 2010-06-30 20:31:21 -0400 |
|---|---|---|
| committer | Frederic Weisbecker <fweisbec@gmail.com> | 2010-08-18 19:32:11 -0400 |
| commit | f72c1a931e311bb7780fee19e41a89ac42cab50e (patch) | |
| tree | 470aa111c535af47d8444a249c83b5d360806e69 | |
| parent | 56962b4449af34070bb1994621ef4f0265eed4d8 (diff) | |
perf: Factorize callchain context handling
Store the kernel and user contexts from the generic layer instead
of archs, this gathers some repetitive code.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Acked-by: Paul Mackerras <paulus@samba.org>
Tested-by: Will Deacon <will.deacon@arm.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: David Miller <davem@davemloft.net>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Borislav Petkov <bp@amd64.org>
| -rw-r--r-- | arch/arm/kernel/perf_event.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/perf_callchain.c | 3 | ||||
| -rw-r--r-- | arch/sh/kernel/perf_callchain.c | 1 | ||||
| -rw-r--r-- | arch/sparc/kernel/perf_event.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 2 | ||||
| -rw-r--r-- | kernel/perf_event.c | 5 |
6 files changed, 4 insertions, 12 deletions
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 0e3bbdb15927..64ca8c3ab94b 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c | |||
| @@ -3049,7 +3049,6 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) | |||
| 3049 | { | 3049 | { |
| 3050 | struct frame_tail *tail; | 3050 | struct frame_tail *tail; |
| 3051 | 3051 | ||
| 3052 | perf_callchain_store(entry, PERF_CONTEXT_USER); | ||
| 3053 | 3052 | ||
| 3054 | tail = (struct frame_tail *)regs->ARM_fp - 1; | 3053 | tail = (struct frame_tail *)regs->ARM_fp - 1; |
| 3055 | 3054 | ||
| @@ -3076,7 +3075,6 @@ perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) | |||
| 3076 | { | 3075 | { |
| 3077 | struct stackframe fr; | 3076 | struct stackframe fr; |
| 3078 | 3077 | ||
| 3079 | perf_callchain_store(entry, PERF_CONTEXT_KERNEL); | ||
| 3080 | fr.fp = regs->ARM_fp; | 3078 | fr.fp = regs->ARM_fp; |
| 3081 | fr.sp = regs->ARM_sp; | 3079 | fr.sp = regs->ARM_sp; |
| 3082 | fr.lr = regs->ARM_lr; | 3080 | fr.lr = regs->ARM_lr; |
diff --git a/arch/powerpc/kernel/perf_callchain.c b/arch/powerpc/kernel/perf_callchain.c index f7a85ede8407..d05ae4204bbf 100644 --- a/arch/powerpc/kernel/perf_callchain.c +++ b/arch/powerpc/kernel/perf_callchain.c | |||
| @@ -57,7 +57,6 @@ perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) | |||
| 57 | 57 | ||
| 58 | lr = regs->link; | 58 | lr = regs->link; |
| 59 | sp = regs->gpr[1]; | 59 | sp = regs->gpr[1]; |
| 60 | perf_callchain_store(entry, PERF_CONTEXT_KERNEL); | ||
| 61 | perf_callchain_store(entry, regs->nip); | 60 | perf_callchain_store(entry, regs->nip); |
| 62 | 61 | ||
| 63 | if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD)) | 62 | if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD)) |
| @@ -234,7 +233,6 @@ static void perf_callchain_user_64(struct perf_callchain_entry *entry, | |||
| 234 | next_ip = regs->nip; | 233 | next_ip = regs->nip; |
| 235 | lr = regs->link; | 234 | lr = regs->link; |
| 236 | sp = regs->gpr[1]; | 235 | sp = regs->gpr[1]; |
| 237 | perf_callchain_store(entry, PERF_CONTEXT_USER); | ||
| 238 | perf_callchain_store(entry, next_ip); | 236 | perf_callchain_store(entry, next_ip); |
| 239 | 237 | ||
| 240 | for (;;) { | 238 | for (;;) { |
| @@ -435,7 +433,6 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, | |||
| 435 | next_ip = regs->nip; | 433 | next_ip = regs->nip; |
| 436 | lr = regs->link; | 434 | lr = regs->link; |
| 437 | sp = regs->gpr[1]; | 435 | sp = regs->gpr[1]; |
| 438 | perf_callchain_store(entry, PERF_CONTEXT_USER); | ||
| 439 | perf_callchain_store(entry, next_ip); | 436 | perf_callchain_store(entry, next_ip); |
| 440 | 437 | ||
| 441 | while (entry->nr < PERF_MAX_STACK_DEPTH) { | 438 | while (entry->nr < PERF_MAX_STACK_DEPTH) { |
diff --git a/arch/sh/kernel/perf_callchain.c b/arch/sh/kernel/perf_callchain.c index ef076a91292a..d5ca1ef50fa9 100644 --- a/arch/sh/kernel/perf_callchain.c +++ b/arch/sh/kernel/perf_callchain.c | |||
| @@ -47,7 +47,6 @@ static const struct stacktrace_ops callchain_ops = { | |||
| 47 | void | 47 | void |
| 48 | perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) | 48 | perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) |
| 49 | { | 49 | { |
| 50 | perf_callchain_store(entry, PERF_CONTEXT_KERNEL); | ||
| 51 | perf_callchain_store(entry, regs->pc); | 50 | perf_callchain_store(entry, regs->pc); |
| 52 | 51 | ||
| 53 | unwind_stack(NULL, regs, NULL, &callchain_ops, entry); | 52 | unwind_stack(NULL, regs, NULL, &callchain_ops, entry); |
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 460162d74aba..4bc402938575 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c | |||
| @@ -1293,7 +1293,6 @@ void perf_callchain_kernel(struct perf_callchain_entry *entry, | |||
| 1293 | 1293 | ||
| 1294 | stack_trace_flush(); | 1294 | stack_trace_flush(); |
| 1295 | 1295 | ||
| 1296 | perf_callchain_store(entry, PERF_CONTEXT_KERNEL); | ||
| 1297 | perf_callchain_store(entry, regs->tpc); | 1296 | perf_callchain_store(entry, regs->tpc); |
| 1298 | 1297 | ||
| 1299 | ksp = regs->u_regs[UREG_I6]; | 1298 | ksp = regs->u_regs[UREG_I6]; |
| @@ -1337,7 +1336,6 @@ static void perf_callchain_user_64(struct perf_callchain_entry *entry, | |||
| 1337 | { | 1336 | { |
| 1338 | unsigned long ufp; | 1337 | unsigned long ufp; |
| 1339 | 1338 | ||
| 1340 | perf_callchain_store(entry, PERF_CONTEXT_USER); | ||
| 1341 | perf_callchain_store(entry, regs->tpc); | 1339 | perf_callchain_store(entry, regs->tpc); |
| 1342 | 1340 | ||
| 1343 | ufp = regs->u_regs[UREG_I6] + STACK_BIAS; | 1341 | ufp = regs->u_regs[UREG_I6] + STACK_BIAS; |
| @@ -1360,7 +1358,6 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, | |||
| 1360 | { | 1358 | { |
| 1361 | unsigned long ufp; | 1359 | unsigned long ufp; |
| 1362 | 1360 | ||
| 1363 | perf_callchain_store(entry, PERF_CONTEXT_USER); | ||
| 1364 | perf_callchain_store(entry, regs->tpc); | 1361 | perf_callchain_store(entry, regs->tpc); |
| 1365 | 1362 | ||
| 1366 | ufp = regs->u_regs[UREG_I6] & 0xffffffffUL; | 1363 | ufp = regs->u_regs[UREG_I6] & 0xffffffffUL; |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 39f8421b86e6..a3c922288cc0 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
| @@ -1608,7 +1608,6 @@ static const struct stacktrace_ops backtrace_ops = { | |||
| 1608 | void | 1608 | void |
| 1609 | perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) | 1609 | perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) |
| 1610 | { | 1610 | { |
| 1611 | perf_callchain_store(entry, PERF_CONTEXT_KERNEL); | ||
| 1612 | perf_callchain_store(entry, regs->ip); | 1611 | perf_callchain_store(entry, regs->ip); |
| 1613 | 1612 | ||
| 1614 | dump_trace(NULL, regs, NULL, regs->bp, &backtrace_ops, entry); | 1613 | dump_trace(NULL, regs, NULL, regs->bp, &backtrace_ops, entry); |
| @@ -1660,7 +1659,6 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) | |||
| 1660 | 1659 | ||
| 1661 | fp = (void __user *)regs->bp; | 1660 | fp = (void __user *)regs->bp; |
| 1662 | 1661 | ||
| 1663 | perf_callchain_store(entry, PERF_CONTEXT_USER); | ||
| 1664 | perf_callchain_store(entry, regs->ip); | 1662 | perf_callchain_store(entry, regs->ip); |
| 1665 | 1663 | ||
| 1666 | if (perf_callchain_user32(regs, entry)) | 1664 | if (perf_callchain_user32(regs, entry)) |
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 02efde6c8798..615d024894cf 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
| @@ -2969,6 +2969,7 @@ static struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) | |||
| 2969 | entry->nr = 0; | 2969 | entry->nr = 0; |
| 2970 | 2970 | ||
| 2971 | if (!user_mode(regs)) { | 2971 | if (!user_mode(regs)) { |
| 2972 | perf_callchain_store(entry, PERF_CONTEXT_KERNEL); | ||
| 2972 | perf_callchain_kernel(entry, regs); | 2973 | perf_callchain_kernel(entry, regs); |
| 2973 | if (current->mm) | 2974 | if (current->mm) |
| 2974 | regs = task_pt_regs(current); | 2975 | regs = task_pt_regs(current); |
| @@ -2976,8 +2977,10 @@ static struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) | |||
| 2976 | regs = NULL; | 2977 | regs = NULL; |
| 2977 | } | 2978 | } |
| 2978 | 2979 | ||
| 2979 | if (regs) | 2980 | if (regs) { |
| 2981 | perf_callchain_store(entry, PERF_CONTEXT_USER); | ||
| 2980 | perf_callchain_user(entry, regs); | 2982 | perf_callchain_user(entry, regs); |
| 2983 | } | ||
| 2981 | 2984 | ||
| 2982 | return entry; | 2985 | return entry; |
| 2983 | } | 2986 | } |
