diff options
-rw-r--r-- | arch/i386/kernel/stacktrace.c | 11 | ||||
-rw-r--r-- | arch/s390/kernel/stacktrace.c | 17 | ||||
-rw-r--r-- | arch/x86_64/kernel/stacktrace.c | 14 | ||||
-rw-r--r-- | include/linux/stacktrace.h | 7 | ||||
-rw-r--r-- | kernel/lockdep.c | 5 |
5 files changed, 24 insertions, 30 deletions
diff --git a/arch/i386/kernel/stacktrace.c b/arch/i386/kernel/stacktrace.c index e62a037ab399..ae3c32a87add 100644 --- a/arch/i386/kernel/stacktrace.c +++ b/arch/i386/kernel/stacktrace.c | |||
@@ -61,12 +61,8 @@ save_context_stack(struct stack_trace *trace, unsigned int skip, | |||
61 | 61 | ||
62 | /* | 62 | /* |
63 | * Save stack-backtrace addresses into a stack_trace buffer. | 63 | * Save stack-backtrace addresses into a stack_trace buffer. |
64 | * If all_contexts is set, all contexts (hardirq, softirq and process) | ||
65 | * are saved. If not set then only the current context is saved. | ||
66 | */ | 64 | */ |
67 | void save_stack_trace(struct stack_trace *trace, | 65 | void save_stack_trace(struct stack_trace *trace, struct task_struct *task) |
68 | struct task_struct *task, int all_contexts, | ||
69 | unsigned int skip) | ||
70 | { | 66 | { |
71 | unsigned long ebp; | 67 | unsigned long ebp; |
72 | unsigned long *stack = &ebp; | 68 | unsigned long *stack = &ebp; |
@@ -85,10 +81,9 @@ void save_stack_trace(struct stack_trace *trace, | |||
85 | struct thread_info *context = (struct thread_info *) | 81 | struct thread_info *context = (struct thread_info *) |
86 | ((unsigned long)stack & (~(THREAD_SIZE - 1))); | 82 | ((unsigned long)stack & (~(THREAD_SIZE - 1))); |
87 | 83 | ||
88 | ebp = save_context_stack(trace, skip, context, stack, ebp); | 84 | ebp = save_context_stack(trace, trace->skip, context, stack, ebp); |
89 | stack = (unsigned long *)context->previous_esp; | 85 | stack = (unsigned long *)context->previous_esp; |
90 | if (!all_contexts || !stack || | 86 | if (!stack || trace->nr_entries >= trace->max_entries) |
91 | trace->nr_entries >= trace->max_entries) | ||
92 | break; | 87 | break; |
93 | trace->entries[trace->nr_entries++] = ULONG_MAX; | 88 | trace->entries[trace->nr_entries++] = ULONG_MAX; |
94 | if (trace->nr_entries >= trace->max_entries) | 89 | if (trace->nr_entries >= trace->max_entries) |
diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c index de83f38288d0..d9428a0fc8fb 100644 --- a/arch/s390/kernel/stacktrace.c +++ b/arch/s390/kernel/stacktrace.c | |||
@@ -59,9 +59,7 @@ static inline unsigned long save_context_stack(struct stack_trace *trace, | |||
59 | } | 59 | } |
60 | } | 60 | } |
61 | 61 | ||
62 | void save_stack_trace(struct stack_trace *trace, | 62 | void save_stack_trace(struct stack_trace *trace, struct task_struct *task) |
63 | struct task_struct *task, int all_contexts, | ||
64 | unsigned int skip) | ||
65 | { | 63 | { |
66 | register unsigned long sp asm ("15"); | 64 | register unsigned long sp asm ("15"); |
67 | unsigned long orig_sp; | 65 | unsigned long orig_sp; |
@@ -69,22 +67,23 @@ void save_stack_trace(struct stack_trace *trace, | |||
69 | sp &= PSW_ADDR_INSN; | 67 | sp &= PSW_ADDR_INSN; |
70 | orig_sp = sp; | 68 | orig_sp = sp; |
71 | 69 | ||
72 | sp = save_context_stack(trace, &skip, sp, | 70 | sp = save_context_stack(trace, &trace->skip, sp, |
73 | S390_lowcore.panic_stack - PAGE_SIZE, | 71 | S390_lowcore.panic_stack - PAGE_SIZE, |
74 | S390_lowcore.panic_stack); | 72 | S390_lowcore.panic_stack); |
75 | if ((sp != orig_sp) && !all_contexts) | 73 | if ((sp != orig_sp) && !trace->all_contexts) |
76 | return; | 74 | return; |
77 | sp = save_context_stack(trace, &skip, sp, | 75 | sp = save_context_stack(trace, &trace->skip, sp, |
78 | S390_lowcore.async_stack - ASYNC_SIZE, | 76 | S390_lowcore.async_stack - ASYNC_SIZE, |
79 | S390_lowcore.async_stack); | 77 | S390_lowcore.async_stack); |
80 | if ((sp != orig_sp) && !all_contexts) | 78 | if ((sp != orig_sp) && !trace->all_contexts) |
81 | return; | 79 | return; |
82 | if (task) | 80 | if (task) |
83 | save_context_stack(trace, &skip, sp, | 81 | save_context_stack(trace, &trace->skip, sp, |
84 | (unsigned long) task_stack_page(task), | 82 | (unsigned long) task_stack_page(task), |
85 | (unsigned long) task_stack_page(task) + THREAD_SIZE); | 83 | (unsigned long) task_stack_page(task) + THREAD_SIZE); |
86 | else | 84 | else |
87 | save_context_stack(trace, &skip, sp, S390_lowcore.thread_info, | 85 | save_context_stack(trace, &trace->skip, sp, |
86 | S390_lowcore.thread_info, | ||
88 | S390_lowcore.thread_info + THREAD_SIZE); | 87 | S390_lowcore.thread_info + THREAD_SIZE); |
89 | return; | 88 | return; |
90 | } | 89 | } |
diff --git a/arch/x86_64/kernel/stacktrace.c b/arch/x86_64/kernel/stacktrace.c index 32cf55eb9af8..1c022af8fe1e 100644 --- a/arch/x86_64/kernel/stacktrace.c +++ b/arch/x86_64/kernel/stacktrace.c | |||
@@ -109,9 +109,10 @@ out_restore: | |||
109 | * Save stack-backtrace addresses into a stack_trace buffer: | 109 | * Save stack-backtrace addresses into a stack_trace buffer: |
110 | */ | 110 | */ |
111 | static inline unsigned long | 111 | static inline unsigned long |
112 | save_context_stack(struct stack_trace *trace, unsigned int skip, | 112 | save_context_stack(struct stack_trace *trace, |
113 | unsigned long stack, unsigned long stack_end) | 113 | unsigned long stack, unsigned long stack_end) |
114 | { | 114 | { |
115 | int skip = trace->skip; | ||
115 | unsigned long addr; | 116 | unsigned long addr; |
116 | 117 | ||
117 | #ifdef CONFIG_FRAME_POINTER | 118 | #ifdef CONFIG_FRAME_POINTER |
@@ -159,12 +160,8 @@ save_context_stack(struct stack_trace *trace, unsigned int skip, | |||
159 | 160 | ||
160 | /* | 161 | /* |
161 | * Save stack-backtrace addresses into a stack_trace buffer. | 162 | * Save stack-backtrace addresses into a stack_trace buffer. |
162 | * If all_contexts is set, all contexts (hardirq, softirq and process) | ||
163 | * are saved. If not set then only the current context is saved. | ||
164 | */ | 163 | */ |
165 | void save_stack_trace(struct stack_trace *trace, | 164 | void save_stack_trace(struct stack_trace *trace, struct task_struct *task) |
166 | struct task_struct *task, int all_contexts, | ||
167 | unsigned int skip) | ||
168 | { | 165 | { |
169 | unsigned long stack = (unsigned long)&stack; | 166 | unsigned long stack = (unsigned long)&stack; |
170 | int i, nr_stacks = 0, stacks_done[MAX_STACKS]; | 167 | int i, nr_stacks = 0, stacks_done[MAX_STACKS]; |
@@ -207,9 +204,8 @@ void save_stack_trace(struct stack_trace *trace, | |||
207 | return; | 204 | return; |
208 | stacks_done[nr_stacks] = stack_end; | 205 | stacks_done[nr_stacks] = stack_end; |
209 | 206 | ||
210 | stack = save_context_stack(trace, skip, stack, stack_end); | 207 | stack = save_context_stack(trace, stack, stack_end); |
211 | if (!all_contexts || !stack || | 208 | if (!stack || trace->nr_entries >= trace->max_entries) |
212 | trace->nr_entries >= trace->max_entries) | ||
213 | return; | 209 | return; |
214 | trace->entries[trace->nr_entries++] = ULONG_MAX; | 210 | trace->entries[trace->nr_entries++] = ULONG_MAX; |
215 | if (trace->nr_entries >= trace->max_entries) | 211 | if (trace->nr_entries >= trace->max_entries) |
diff --git a/include/linux/stacktrace.h b/include/linux/stacktrace.h index 9cc81e572224..50e2b01e517c 100644 --- a/include/linux/stacktrace.h +++ b/include/linux/stacktrace.h | |||
@@ -5,15 +5,16 @@ | |||
5 | struct stack_trace { | 5 | struct stack_trace { |
6 | unsigned int nr_entries, max_entries; | 6 | unsigned int nr_entries, max_entries; |
7 | unsigned long *entries; | 7 | unsigned long *entries; |
8 | int skip; /* input argument: How many entries to skip */ | ||
9 | int all_contexts; /* input argument: if true do than one stack */ | ||
8 | }; | 10 | }; |
9 | 11 | ||
10 | extern void save_stack_trace(struct stack_trace *trace, | 12 | extern void save_stack_trace(struct stack_trace *trace, |
11 | struct task_struct *task, int all_contexts, | 13 | struct task_struct *task); |
12 | unsigned int skip); | ||
13 | 14 | ||
14 | extern void print_stack_trace(struct stack_trace *trace, int spaces); | 15 | extern void print_stack_trace(struct stack_trace *trace, int spaces); |
15 | #else | 16 | #else |
16 | # define save_stack_trace(trace, task, all, skip) do { } while (0) | 17 | # define save_stack_trace(trace, task) do { } while (0) |
17 | # define print_stack_trace(trace) do { } while (0) | 18 | # define print_stack_trace(trace) do { } while (0) |
18 | #endif | 19 | #endif |
19 | 20 | ||
diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 9bad17884513..900b4cb1a024 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c | |||
@@ -224,7 +224,10 @@ static int save_trace(struct stack_trace *trace) | |||
224 | trace->max_entries = MAX_STACK_TRACE_ENTRIES - nr_stack_trace_entries; | 224 | trace->max_entries = MAX_STACK_TRACE_ENTRIES - nr_stack_trace_entries; |
225 | trace->entries = stack_trace + nr_stack_trace_entries; | 225 | trace->entries = stack_trace + nr_stack_trace_entries; |
226 | 226 | ||
227 | save_stack_trace(trace, NULL, 0, 3); | 227 | trace->skip = 3; |
228 | trace->all_contexts = 0; | ||
229 | |||
230 | save_stack_trace(trace, NULL); | ||
228 | 231 | ||
229 | trace->max_entries = trace->nr_entries; | 232 | trace->max_entries = trace->nr_entries; |
230 | 233 | ||