diff options
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 25 | ||||
-rw-r--r-- | arch/x86/kernel/dumpstack.h | 15 | ||||
-rw-r--r-- | arch/x86/kernel/dumpstack_64.c | 4 |
3 files changed, 33 insertions, 11 deletions
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 5586a02067d..978d297170a 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -798,7 +798,6 @@ void hw_perf_enable(void) | |||
798 | * step2: reprogram moved events into new counters | 798 | * step2: reprogram moved events into new counters |
799 | */ | 799 | */ |
800 | for (i = 0; i < n_running; i++) { | 800 | for (i = 0; i < n_running; i++) { |
801 | |||
802 | event = cpuc->event_list[i]; | 801 | event = cpuc->event_list[i]; |
803 | hwc = &event->hw; | 802 | hwc = &event->hw; |
804 | 803 | ||
@@ -813,21 +812,16 @@ void hw_perf_enable(void) | |||
813 | continue; | 812 | continue; |
814 | 813 | ||
815 | x86_pmu_stop(event); | 814 | x86_pmu_stop(event); |
816 | |||
817 | hwc->idx = -1; | ||
818 | } | 815 | } |
819 | 816 | ||
820 | for (i = 0; i < cpuc->n_events; i++) { | 817 | for (i = 0; i < cpuc->n_events; i++) { |
821 | |||
822 | event = cpuc->event_list[i]; | 818 | event = cpuc->event_list[i]; |
823 | hwc = &event->hw; | 819 | hwc = &event->hw; |
824 | 820 | ||
825 | if (i < n_running && | 821 | if (!match_prev_assignment(hwc, cpuc, i)) |
826 | match_prev_assignment(hwc, cpuc, i)) | ||
827 | continue; | ||
828 | |||
829 | if (hwc->idx == -1) | ||
830 | x86_assign_hw_event(event, cpuc, i); | 822 | x86_assign_hw_event(event, cpuc, i); |
823 | else if (i < n_running) | ||
824 | continue; | ||
831 | 825 | ||
832 | x86_pmu_start(event); | 826 | x86_pmu_start(event); |
833 | } | 827 | } |
@@ -1700,3 +1694,16 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) | |||
1700 | 1694 | ||
1701 | return entry; | 1695 | return entry; |
1702 | } | 1696 | } |
1697 | |||
1698 | void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip) | ||
1699 | { | ||
1700 | regs->ip = ip; | ||
1701 | /* | ||
1702 | * perf_arch_fetch_caller_regs adds another call, we need to increment | ||
1703 | * the skip level | ||
1704 | */ | ||
1705 | regs->bp = rewind_frame_pointer(skip + 1); | ||
1706 | regs->cs = __KERNEL_CS; | ||
1707 | local_save_flags(regs->flags); | ||
1708 | } | ||
1709 | EXPORT_SYMBOL_GPL(perf_arch_fetch_caller_regs); | ||
diff --git a/arch/x86/kernel/dumpstack.h b/arch/x86/kernel/dumpstack.h index 4fd1420faff..29e5f7c845b 100644 --- a/arch/x86/kernel/dumpstack.h +++ b/arch/x86/kernel/dumpstack.h | |||
@@ -29,4 +29,19 @@ struct stack_frame { | |||
29 | struct stack_frame *next_frame; | 29 | struct stack_frame *next_frame; |
30 | unsigned long return_address; | 30 | unsigned long return_address; |
31 | }; | 31 | }; |
32 | |||
33 | static inline unsigned long rewind_frame_pointer(int n) | ||
34 | { | ||
35 | struct stack_frame *frame; | ||
36 | |||
37 | get_bp(frame); | ||
38 | |||
39 | #ifdef CONFIG_FRAME_POINTER | ||
40 | while (n--) | ||
41 | frame = frame->next_frame; | ||
32 | #endif | 42 | #endif |
43 | |||
44 | return (unsigned long)frame; | ||
45 | } | ||
46 | |||
47 | #endif /* DUMPSTACK_H */ | ||
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index d5e2a2ebb62..272c9f1f05f 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c | |||
@@ -208,7 +208,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, | |||
208 | if (in_irq_stack(stack, irq_stack, irq_stack_end)) { | 208 | if (in_irq_stack(stack, irq_stack, irq_stack_end)) { |
209 | if (ops->stack(data, "IRQ") < 0) | 209 | if (ops->stack(data, "IRQ") < 0) |
210 | break; | 210 | break; |
211 | bp = print_context_stack(tinfo, stack, bp, | 211 | bp = ops->walk_stack(tinfo, stack, bp, |
212 | ops, data, irq_stack_end, &graph); | 212 | ops, data, irq_stack_end, &graph); |
213 | /* | 213 | /* |
214 | * We link to the next stack (which would be | 214 | * We link to the next stack (which would be |
@@ -229,7 +229,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, | |||
229 | /* | 229 | /* |
230 | * This handles the process stack: | 230 | * This handles the process stack: |
231 | */ | 231 | */ |
232 | bp = print_context_stack(tinfo, stack, bp, ops, data, NULL, &graph); | 232 | bp = ops->walk_stack(tinfo, stack, bp, ops, data, NULL, &graph); |
233 | put_cpu(); | 233 | put_cpu(); |
234 | } | 234 | } |
235 | EXPORT_SYMBOL(dump_trace); | 235 | EXPORT_SYMBOL(dump_trace); |