Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (57 commits) x86, perf events: Check if we have APIC enabled perf_event: Fix variable initialization in other codepaths perf kmem: Fix unused argument build warning perf symbols: perf_header__read_build_ids() offset'n'size should be u64 perf symbols: dsos__read_build_ids() should read both user and kernel buildids perf tools: Align long options which have no short forms perf kmem: Show usage if no option is specified sched: Mark sched_clock() as notrace perf sched: Add max delay time snapshot perf tools: Correct size given to memset perf_event: Fix perf_swevent_hrtimer() variable initialization perf sched: Fix for getting task's execution time tracing/kprobes: Fix field creation's bad error handling perf_event: Cleanup for cpu_clock_perf_event_update() perf_event: Allocate children's perf_event_ctxp at the right time perf_event: Clean up __perf_event_init_context() hw-breakpoints: Modify breakpoints without unregistering them perf probe: Update perf-probe document perf probe: Support --del option trace-kprobe: Support delete probe syntax ...
This commit is contained in:
@@ -103,6 +103,35 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline int
|
||||
in_irq_stack(unsigned long *stack, unsigned long *irq_stack,
|
||||
unsigned long *irq_stack_end)
|
||||
{
|
||||
return (stack >= irq_stack && stack < irq_stack_end);
|
||||
}
|
||||
|
||||
/*
|
||||
* We are returning from the irq stack and go to the previous one.
|
||||
* If the previous stack is also in the irq stack, then bp in the first
|
||||
* frame of the irq stack points to the previous, interrupted one.
|
||||
* Otherwise we have another level of indirection: We first save
|
||||
* the bp of the previous stack, then we switch the stack to the irq one
|
||||
* and save a new bp that links to the previous one.
|
||||
* (See save_args())
|
||||
*/
|
||||
static inline unsigned long
|
||||
fixup_bp_irq_link(unsigned long bp, unsigned long *stack,
|
||||
unsigned long *irq_stack, unsigned long *irq_stack_end)
|
||||
{
|
||||
#ifdef CONFIG_FRAME_POINTER
|
||||
struct stack_frame *frame = (struct stack_frame *)bp;
|
||||
|
||||
if (!in_irq_stack(stack, irq_stack, irq_stack_end))
|
||||
return (unsigned long)frame->next_frame;
|
||||
#endif
|
||||
return bp;
|
||||
}
|
||||
|
||||
/*
|
||||
* x86-64 can have up to three kernel stacks:
|
||||
* process stack
|
||||
@@ -175,7 +204,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
|
||||
irq_stack = irq_stack_end -
|
||||
(IRQ_STACK_SIZE - 64) / sizeof(*irq_stack);
|
||||
|
||||
if (stack >= irq_stack && stack < irq_stack_end) {
|
||||
if (in_irq_stack(stack, irq_stack, irq_stack_end)) {
|
||||
if (ops->stack(data, "IRQ") < 0)
|
||||
break;
|
||||
bp = print_context_stack(tinfo, stack, bp,
|
||||
@@ -186,6 +215,8 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
|
||||
* pointer (index -1 to end) in the IRQ stack:
|
||||
*/
|
||||
stack = (unsigned long *) (irq_stack_end[-1]);
|
||||
bp = fixup_bp_irq_link(bp, stack, irq_stack,
|
||||
irq_stack_end);
|
||||
irq_stack_end = NULL;
|
||||
ops->stack(data, "EOI");
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user