diff options
author | Steven Rostedt (Red Hat) <rostedt@goodmis.org> | 2014-04-02 13:26:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-02 14:46:50 -0400 |
commit | 63c95654d8256db8aed2a4699ad6eba359400ef8 (patch) | |
tree | 33360aec89575c354bc7b086a2a0ad88f5ed9e51 | |
parent | 1aabc5990d205cdb0789a1c26143c53601e9bb07 (diff) |
x86: Fix dumpstack_64 irq stack handling
Commit 2223f6f6eeaa "x86: Clean up dumpstack_64.c code" changed
the irq_stack processing a little from what it was before.
The irq_stack_end variable needed to be cleared after its first
use. By setting irq_stack to the per cpu irq_stack and passing
that to analyze_stack(), and then clearing it after it is processed,
we can get back the original behavior.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/x86/kernel/dumpstack_64.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index 74c262a9b9f1..1abcb50b48ae 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c | |||
@@ -116,9 +116,9 @@ enum stack_type { | |||
116 | 116 | ||
117 | static enum stack_type | 117 | static enum stack_type |
118 | analyze_stack(int cpu, struct task_struct *task, unsigned long *stack, | 118 | analyze_stack(int cpu, struct task_struct *task, unsigned long *stack, |
119 | unsigned long **stack_end, unsigned *used, char **id) | 119 | unsigned long **stack_end, unsigned long *irq_stack, |
120 | unsigned *used, char **id) | ||
120 | { | 121 | { |
121 | unsigned long *irq_stack; | ||
122 | unsigned long addr; | 122 | unsigned long addr; |
123 | 123 | ||
124 | addr = ((unsigned long)stack & (~(THREAD_SIZE - 1))); | 124 | addr = ((unsigned long)stack & (~(THREAD_SIZE - 1))); |
@@ -130,11 +130,11 @@ analyze_stack(int cpu, struct task_struct *task, unsigned long *stack, | |||
130 | if (*stack_end) | 130 | if (*stack_end) |
131 | return STACK_IS_EXCEPTION; | 131 | return STACK_IS_EXCEPTION; |
132 | 132 | ||
133 | *stack_end = (unsigned long *)per_cpu(irq_stack_ptr, cpu); | 133 | if (!irq_stack) |
134 | if (!*stack_end) | 134 | return STACK_IS_NORMAL; |
135 | return STACK_IS_UNKNOWN; | ||
136 | 135 | ||
137 | irq_stack = *stack_end - irq_stack_size; | 136 | *stack_end = irq_stack; |
137 | irq_stack = irq_stack - irq_stack_size; | ||
138 | 138 | ||
139 | if (in_irq_stack(stack, irq_stack, *stack_end)) | 139 | if (in_irq_stack(stack, irq_stack, *stack_end)) |
140 | return STACK_IS_IRQ; | 140 | return STACK_IS_IRQ; |
@@ -155,7 +155,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, | |||
155 | { | 155 | { |
156 | const unsigned cpu = get_cpu(); | 156 | const unsigned cpu = get_cpu(); |
157 | struct thread_info *tinfo; | 157 | struct thread_info *tinfo; |
158 | unsigned long *irq_stack; | 158 | unsigned long *irq_stack = (unsigned long *)per_cpu(irq_stack_ptr, cpu); |
159 | unsigned long dummy; | 159 | unsigned long dummy; |
160 | unsigned used = 0; | 160 | unsigned used = 0; |
161 | int graph = 0; | 161 | int graph = 0; |
@@ -186,7 +186,8 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, | |||
186 | enum stack_type stype; | 186 | enum stack_type stype; |
187 | char *id; | 187 | char *id; |
188 | 188 | ||
189 | stype = analyze_stack(cpu, task, stack, &stack_end, &used, &id); | 189 | stype = analyze_stack(cpu, task, stack, &stack_end, |
190 | irq_stack, &used, &id); | ||
190 | 191 | ||
191 | /* Default finish unless specified to continue */ | 192 | /* Default finish unless specified to continue */ |
192 | done = 1; | 193 | done = 1; |
@@ -226,7 +227,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, | |||
226 | * pointer (index -1 to end) in the IRQ stack: | 227 | * pointer (index -1 to end) in the IRQ stack: |
227 | */ | 228 | */ |
228 | stack = (unsigned long *) (stack_end[-1]); | 229 | stack = (unsigned long *) (stack_end[-1]); |
229 | irq_stack = stack_end - irq_stack_size; | 230 | irq_stack = NULL; |
230 | ops->stack(data, "EOI"); | 231 | ops->stack(data, "EOI"); |
231 | done = 0; | 232 | done = 0; |
232 | break; | 233 | break; |