aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-04-30 18:27:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-04-30 20:04:02 -0400
commit196779b9b4ce1922afabdc20d0270720603bd46c (patch)
tree9628ad58fef85b4cc060f434e01fe50a8e0e333c
parent89e3f23da9c827bfa9806c3d4da83a12c1c8543a (diff)
dump_stack: consolidate dump_stack() implementations and unify their behaviors
Both dump_stack() and show_stack() are currently implemented by each architecture. show_stack(NULL, NULL) dumps the backtrace for the current task as does dump_stack(). On some archs, dump_stack() prints extra information - pid, utsname and so on - in addition to the backtrace while the two are identical on other archs. The usages in arch-independent code of the two functions indicate show_stack(NULL, NULL) should print out bare backtrace while dump_stack() is used for debugging purposes when something went wrong, so it does make sense to print additional information on the task which triggered dump_stack(). There's no reason to require archs to implement two separate but mostly identical functions. It leads to unnecessary subtle information. This patch expands the dummy fallback dump_stack() implementation in lib/dump_stack.c such that it prints out debug information (taken from x86) and invokes show_stack(NULL, NULL) and drops arch-specific dump_stack() implementations in all archs except blackfin. Blackfin's dump_stack() does something wonky that I don't understand. Debug information can be printed separately by calling dump_stack_print_info() so that arch-specific dump_stack() implementation can still emit the same debug information. This is used in blackfin. This patch brings the following behavior changes. * On some archs, an extra level in backtrace for show_stack() could be printed. This is because the top frame was determined in dump_stack() on those archs while generic dump_stack() can't do that reliably. It can be compensated by inlining dump_stack() but not sure whether that'd be necessary. * Most archs didn't use to print debug info on dump_stack(). They do now. An example WARN dump follows. WARNING: at kernel/workqueue.c:4841 init_workqueues+0x35/0x505() Hardware name: empty Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.9.0-rc1-work+ #9 0000000000000009 ffff88007c861e08 ffffffff81c614dc ffff88007c861e48 ffffffff8108f50f ffffffff82228240 0000000000000040 ffffffff8234a03c 0000000000000000 0000000000000000 0000000000000000 ffff88007c861e58 Call Trace: [<ffffffff81c614dc>] dump_stack+0x19/0x1b [<ffffffff8108f50f>] warn_slowpath_common+0x7f/0xc0 [<ffffffff8108f56a>] warn_slowpath_null+0x1a/0x20 [<ffffffff8234a071>] init_workqueues+0x35/0x505 ... v2: CPU number added to the generic debug info as requested by s390 folks and dropped the s390 specific dump_stack(). This loses %ksp from the debug message which the maintainers think isn't important enough to keep the s390-specific dump_stack() implementation. dump_stack_print_info() is moved to kernel/printk.c from lib/dump_stack.c. Because linkage is per objecct file, dump_stack_print_info() living in the same lib file as generic dump_stack() means that archs which implement custom dump_stack() - at this point, only blackfin - can't use dump_stack_print_info() as that will bring in the generic version of dump_stack() too. v1 The v1 patch broke build on blackfin due to this issue. The build breakage was reported by Fengguang Wu. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: David S. Miller <davem@davemloft.net> Acked-by: Vineet Gupta <vgupta@synopsys.com> Acked-by: Jesper Nilsson <jesper.nilsson@axis.com> Acked-by: Vineet Gupta <vgupta@synopsys.com> Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com> [s390 bits] Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Mike Frysinger <vapier@gentoo.org> Cc: Fengguang Wu <fengguang.wu@intel.com> Cc: Bjorn Helgaas <bhelgaas@google.com> Cc: Sam Ravnborg <sam@ravnborg.org> Acked-by: Richard Kuo <rkuo@codeaurora.org> [hexagon bits] Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/alpha/kernel/traps.c7
-rw-r--r--arch/arc/kernel/stacktrace.c7
-rw-r--r--arch/arm/kernel/traps.c7
-rw-r--r--arch/arm64/kernel/traps.c7
-rw-r--r--arch/avr32/kernel/process.c8
-rw-r--r--arch/blackfin/kernel/dumpstack.c1
-rw-r--r--arch/c6x/kernel/traps.c9
-rw-r--r--arch/cris/kernel/traps.c7
-rw-r--r--arch/frv/kernel/traps.c11
-rw-r--r--arch/h8300/kernel/traps.c7
-rw-r--r--arch/hexagon/kernel/traps.c8
-rw-r--r--arch/ia64/kernel/process.c8
-rw-r--r--arch/m32r/kernel/traps.c9
-rw-r--r--arch/m68k/kernel/traps.c12
-rw-r--r--arch/metag/kernel/traps.c6
-rw-r--r--arch/microblaze/kernel/traps.c6
-rw-r--r--arch/mips/kernel/traps.c13
-rw-r--r--arch/mn10300/kernel/traps.c11
-rw-r--r--arch/openrisc/kernel/traps.c11
-rw-r--r--arch/parisc/kernel/traps.c8
-rw-r--r--arch/powerpc/kernel/process.c6
-rw-r--r--arch/s390/kernel/dumpstack.c17
-rw-r--r--arch/score/kernel/traps.c10
-rw-r--r--arch/sh/kernel/dumpstack.c6
-rw-r--r--arch/sparc/kernel/process_32.c7
-rw-r--r--arch/sparc/kernel/traps_64.c7
-rw-r--r--arch/um/kernel/sysrq.c12
-rw-r--r--arch/unicore32/kernel/traps.c6
-rw-r--r--arch/x86/kernel/dumpstack.c18
-rw-r--r--arch/xtensa/kernel/traps.c8
-rw-r--r--include/linux/printk.h5
-rw-r--r--kernel/printk.c18
-rw-r--r--lib/dump_stack.c11
33 files changed, 32 insertions, 262 deletions
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index 4037461a6493..affccb959a9e 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -169,13 +169,6 @@ void show_stack(struct task_struct *task, unsigned long *sp)
169 dik_show_trace(sp); 169 dik_show_trace(sp);
170} 170}
171 171
172void dump_stack(void)
173{
174 show_stack(NULL, NULL);
175}
176
177EXPORT_SYMBOL(dump_stack);
178
179void 172void
180die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15) 173die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
181{ 174{
diff --git a/arch/arc/kernel/stacktrace.c b/arch/arc/kernel/stacktrace.c
index a63ff842564b..ca0207b9d5b6 100644
--- a/arch/arc/kernel/stacktrace.c
+++ b/arch/arc/kernel/stacktrace.c
@@ -220,13 +220,6 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
220 show_stacktrace(tsk, NULL); 220 show_stacktrace(tsk, NULL);
221} 221}
222 222
223/* Expected by Rest of kernel code */
224void dump_stack(void)
225{
226 show_stacktrace(NULL, NULL);
227}
228EXPORT_SYMBOL(dump_stack);
229
230/* Another API expected by schedular, shows up in "ps" as Wait Channel 223/* Another API expected by schedular, shows up in "ps" as Wait Channel
231 * Ofcourse just returning schedule( ) would be pointless so unwind until 224 * Ofcourse just returning schedule( ) would be pointless so unwind until
232 * the function is not in schedular code 225 * the function is not in schedular code
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 1c089119b2d7..18b32e8e4497 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -204,13 +204,6 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
204} 204}
205#endif 205#endif
206 206
207void dump_stack(void)
208{
209 dump_backtrace(NULL, NULL);
210}
211
212EXPORT_SYMBOL(dump_stack);
213
214void show_stack(struct task_struct *tsk, unsigned long *sp) 207void show_stack(struct task_struct *tsk, unsigned long *sp)
215{ 208{
216 dump_backtrace(NULL, tsk); 209 dump_backtrace(NULL, tsk);
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index b3c5f628bdb4..61d7dd29f756 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -167,13 +167,6 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
167 } 167 }
168} 168}
169 169
170void dump_stack(void)
171{
172 dump_backtrace(NULL, NULL);
173}
174
175EXPORT_SYMBOL(dump_stack);
176
177void show_stack(struct task_struct *tsk, unsigned long *sp) 170void show_stack(struct task_struct *tsk, unsigned long *sp)
178{ 171{
179 dump_backtrace(NULL, tsk); 172 dump_backtrace(NULL, tsk);
diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c
index 073c3c2fa521..89a8017e8ca6 100644
--- a/arch/avr32/kernel/process.c
+++ b/arch/avr32/kernel/process.c
@@ -204,14 +204,6 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
204 show_stack_log_lvl(tsk, (unsigned long)stack, NULL, ""); 204 show_stack_log_lvl(tsk, (unsigned long)stack, NULL, "");
205} 205}
206 206
207void dump_stack(void)
208{
209 unsigned long stack;
210
211 show_trace_log_lvl(current, &stack, NULL, "");
212}
213EXPORT_SYMBOL(dump_stack);
214
215static const char *cpu_modes[] = { 207static const char *cpu_modes[] = {
216 "Application", "Supervisor", "Interrupt level 0", "Interrupt level 1", 208 "Application", "Supervisor", "Interrupt level 0", "Interrupt level 1",
217 "Interrupt level 2", "Interrupt level 3", "Exception", "NMI" 209 "Interrupt level 2", "Interrupt level 3", "Exception", "NMI"
diff --git a/arch/blackfin/kernel/dumpstack.c b/arch/blackfin/kernel/dumpstack.c
index 5cfbaa298211..95ba6d9e9a3d 100644
--- a/arch/blackfin/kernel/dumpstack.c
+++ b/arch/blackfin/kernel/dumpstack.c
@@ -168,6 +168,7 @@ void dump_stack(void)
168#endif 168#endif
169 trace_buffer_save(tflags); 169 trace_buffer_save(tflags);
170 dump_bfin_trace_buffer(); 170 dump_bfin_trace_buffer();
171 dump_stack_print_info(KERN_DEFAULT);
171 show_stack(current, &stack); 172 show_stack(current, &stack);
172 trace_buffer_restore(tflags); 173 trace_buffer_restore(tflags);
173} 174}
diff --git a/arch/c6x/kernel/traps.c b/arch/c6x/kernel/traps.c
index 1be74e5b4788..d0b96ef25c17 100644
--- a/arch/c6x/kernel/traps.c
+++ b/arch/c6x/kernel/traps.c
@@ -67,15 +67,6 @@ void show_regs(struct pt_regs *regs)
67 pr_err("A31: %08lx B31: %08lx\n", regs->a31, regs->b31); 67 pr_err("A31: %08lx B31: %08lx\n", regs->a31, regs->b31);
68} 68}
69 69
70void dump_stack(void)
71{
72 unsigned long stack;
73
74 show_stack(current, &stack);
75}
76EXPORT_SYMBOL(dump_stack);
77
78
79void die(char *str, struct pt_regs *fp, int nr) 70void die(char *str, struct pt_regs *fp, int nr)
80{ 71{
81 console_verbose(); 72 console_verbose();
diff --git a/arch/cris/kernel/traps.c b/arch/cris/kernel/traps.c
index a11ad3229f8c..0ffda73734f5 100644
--- a/arch/cris/kernel/traps.c
+++ b/arch/cris/kernel/traps.c
@@ -147,13 +147,6 @@ show_stack(void)
147#endif 147#endif
148 148
149void 149void
150dump_stack(void)
151{
152 show_stack(NULL, NULL);
153}
154EXPORT_SYMBOL(dump_stack);
155
156void
157set_nmi_handler(void (*handler)(struct pt_regs *)) 150set_nmi_handler(void (*handler)(struct pt_regs *))
158{ 151{
159 nmi_handler = handler; 152 nmi_handler = handler;
diff --git a/arch/frv/kernel/traps.c b/arch/frv/kernel/traps.c
index 5cfd1420b091..cfcd802d6f9c 100644
--- a/arch/frv/kernel/traps.c
+++ b/arch/frv/kernel/traps.c
@@ -466,17 +466,6 @@ asmlinkage void compound_exception(unsigned long esfr1,
466 BUG(); 466 BUG();
467} /* end compound_exception() */ 467} /* end compound_exception() */
468 468
469/*****************************************************************************/
470/*
471 * The architecture-independent backtrace generator
472 */
473void dump_stack(void)
474{
475 show_stack(NULL, NULL);
476}
477
478EXPORT_SYMBOL(dump_stack);
479
480void show_stack(struct task_struct *task, unsigned long *sp) 469void show_stack(struct task_struct *task, unsigned long *sp)
481{ 470{
482} 471}
diff --git a/arch/h8300/kernel/traps.c b/arch/h8300/kernel/traps.c
index 7833aa3e7c7d..cfe494dbe3da 100644
--- a/arch/h8300/kernel/traps.c
+++ b/arch/h8300/kernel/traps.c
@@ -164,10 +164,3 @@ void show_trace_task(struct task_struct *tsk)
164{ 164{
165 show_stack(tsk,(unsigned long *)tsk->thread.esp0); 165 show_stack(tsk,(unsigned long *)tsk->thread.esp0);
166} 166}
167
168void dump_stack(void)
169{
170 show_stack(NULL,NULL);
171}
172
173EXPORT_SYMBOL(dump_stack);
diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c
index be5e2dd9c9d3..cc2171b2aa04 100644
--- a/arch/hexagon/kernel/traps.c
+++ b/arch/hexagon/kernel/traps.c
@@ -191,14 +191,6 @@ void show_stack(struct task_struct *task, unsigned long *fp)
191 do_show_stack(task, fp, 0); 191 do_show_stack(task, fp, 0);
192} 192}
193 193
194void dump_stack(void)
195{
196 unsigned long *fp;
197 asm("%0 = r30" : "=r" (fp));
198 show_stack(current, fp);
199}
200EXPORT_SYMBOL(dump_stack);
201
202int die(const char *str, struct pt_regs *regs, long err) 194int die(const char *str, struct pt_regs *regs, long err)
203{ 195{
204 static struct { 196 static struct {
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index a26fc640e4ce..182bd64cc726 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -96,14 +96,6 @@ show_stack (struct task_struct *task, unsigned long *sp)
96} 96}
97 97
98void 98void
99dump_stack (void)
100{
101 show_stack(NULL, NULL);
102}
103
104EXPORT_SYMBOL(dump_stack);
105
106void
107show_regs (struct pt_regs *regs) 99show_regs (struct pt_regs *regs)
108{ 100{
109 unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri; 101 unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
diff --git a/arch/m32r/kernel/traps.c b/arch/m32r/kernel/traps.c
index 9fe3467a5133..a7a424f852e4 100644
--- a/arch/m32r/kernel/traps.c
+++ b/arch/m32r/kernel/traps.c
@@ -167,15 +167,6 @@ void show_stack(struct task_struct *task, unsigned long *sp)
167 show_trace(task, sp); 167 show_trace(task, sp);
168} 168}
169 169
170void dump_stack(void)
171{
172 unsigned long stack;
173
174 show_trace(current, &stack);
175}
176
177EXPORT_SYMBOL(dump_stack);
178
179static void show_registers(struct pt_regs *regs) 170static void show_registers(struct pt_regs *regs)
180{ 171{
181 int i = 0; 172 int i = 0;
diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c
index f32ab22e7ed3..88fcd8c70e7b 100644
--- a/arch/m68k/kernel/traps.c
+++ b/arch/m68k/kernel/traps.c
@@ -992,18 +992,6 @@ void show_stack(struct task_struct *task, unsigned long *stack)
992} 992}
993 993
994/* 994/*
995 * The architecture-independent backtrace generator
996 */
997void dump_stack(void)
998{
999 unsigned long stack;
1000
1001 show_trace(&stack);
1002}
1003
1004EXPORT_SYMBOL(dump_stack);
1005
1006/*
1007 * The vector number returned in the frame pointer may also contain 995 * The vector number returned in the frame pointer may also contain
1008 * the "fs" (Fault Status) bits on ColdFire. These are in the bottom 996 * the "fs" (Fault Status) bits on ColdFire. These are in the bottom
1009 * 2 bits, and upper 2 bits. So we need to mask out the real vector 997 * 2 bits, and upper 2 bits. So we need to mask out the real vector
diff --git a/arch/metag/kernel/traps.c b/arch/metag/kernel/traps.c
index 8961f247b500..2ceeaae5b199 100644
--- a/arch/metag/kernel/traps.c
+++ b/arch/metag/kernel/traps.c
@@ -987,9 +987,3 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
987 987
988 show_trace(tsk, sp, NULL); 988 show_trace(tsk, sp, NULL);
989} 989}
990
991void dump_stack(void)
992{
993 show_stack(NULL, NULL);
994}
995EXPORT_SYMBOL(dump_stack);
diff --git a/arch/microblaze/kernel/traps.c b/arch/microblaze/kernel/traps.c
index 30e6b5004a6a..cb619533a192 100644
--- a/arch/microblaze/kernel/traps.c
+++ b/arch/microblaze/kernel/traps.c
@@ -75,9 +75,3 @@ void show_stack(struct task_struct *task, unsigned long *sp)
75 75
76 debug_show_held_locks(task); 76 debug_show_held_locks(task);
77} 77}
78
79void dump_stack(void)
80{
81 show_stack(NULL, NULL);
82}
83EXPORT_SYMBOL(dump_stack);
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index c3abb88170fc..b512b28cf786 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -206,19 +206,6 @@ void show_stack(struct task_struct *task, unsigned long *sp)
206 show_stacktrace(task, &regs); 206 show_stacktrace(task, &regs);
207} 207}
208 208
209/*
210 * The architecture-independent dump_stack generator
211 */
212void dump_stack(void)
213{
214 struct pt_regs regs;
215
216 prepare_frametrace(&regs);
217 show_backtrace(current, &regs);
218}
219
220EXPORT_SYMBOL(dump_stack);
221
222static void show_code(unsigned int __user *pc) 209static void show_code(unsigned int __user *pc)
223{ 210{
224 long i; 211 long i;
diff --git a/arch/mn10300/kernel/traps.c b/arch/mn10300/kernel/traps.c
index b900e5afa0ae..a7a987c7954f 100644
--- a/arch/mn10300/kernel/traps.c
+++ b/arch/mn10300/kernel/traps.c
@@ -294,17 +294,6 @@ void show_stack(struct task_struct *task, unsigned long *sp)
294} 294}
295 295
296/* 296/*
297 * the architecture-independent dump_stack generator
298 */
299void dump_stack(void)
300{
301 unsigned long stack;
302
303 show_stack(current, &stack);
304}
305EXPORT_SYMBOL(dump_stack);
306
307/*
308 * dump the register file in the specified exception frame 297 * dump the register file in the specified exception frame
309 */ 298 */
310void show_registers_only(struct pt_regs *regs) 299void show_registers_only(struct pt_regs *regs)
diff --git a/arch/openrisc/kernel/traps.c b/arch/openrisc/kernel/traps.c
index 5cce396016d0..3d3f6062f49c 100644
--- a/arch/openrisc/kernel/traps.c
+++ b/arch/openrisc/kernel/traps.c
@@ -105,17 +105,6 @@ void show_trace_task(struct task_struct *tsk)
105 */ 105 */
106} 106}
107 107
108/*
109 * The architecture-independent backtrace generator
110 */
111void dump_stack(void)
112{
113 unsigned long stack;
114
115 show_stack(current, &stack);
116}
117EXPORT_SYMBOL(dump_stack);
118
119void show_registers(struct pt_regs *regs) 108void show_registers(struct pt_regs *regs)
120{ 109{
121 int i; 110 int i;
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index aeb8f8f2c07a..e64cf5f09b62 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -158,14 +158,6 @@ void show_regs(struct pt_regs *regs)
158 } 158 }
159} 159}
160 160
161
162void dump_stack(void)
163{
164 show_stack(NULL, NULL);
165}
166
167EXPORT_SYMBOL(dump_stack);
168
169static void do_show_stack(struct unwind_frame_info *info) 161static void do_show_stack(struct unwind_frame_info *info)
170{ 162{
171 int i = 1; 163 int i = 1;
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 16e77a81ab4f..624d44bb44dc 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1362,12 +1362,6 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
1362 } while (count++ < kstack_depth_to_print); 1362 } while (count++ < kstack_depth_to_print);
1363} 1363}
1364 1364
1365void dump_stack(void)
1366{
1367 show_stack(current, NULL);
1368}
1369EXPORT_SYMBOL(dump_stack);
1370
1371#ifdef CONFIG_PPC64 1365#ifdef CONFIG_PPC64
1372/* Called with hard IRQs off */ 1366/* Called with hard IRQs off */
1373void __ppc64_runlatch_on(void) 1367void __ppc64_runlatch_on(void)
diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c
index 03dce39d01ee..2f1f639d1a3d 100644
--- a/arch/s390/kernel/dumpstack.c
+++ b/arch/s390/kernel/dumpstack.c
@@ -129,23 +129,6 @@ static void show_last_breaking_event(struct pt_regs *regs)
129#endif 129#endif
130} 130}
131 131
132/*
133 * The architecture-independent dump_stack generator
134 */
135void dump_stack(void)
136{
137 printk("CPU: %d %s %s %.*s\n",
138 task_thread_info(current)->cpu, print_tainted(),
139 init_utsname()->release,
140 (int)strcspn(init_utsname()->version, " "),
141 init_utsname()->version);
142 printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
143 current->comm, current->pid, current,
144 (void *) current->thread.ksp);
145 show_stack(NULL, NULL);
146}
147EXPORT_SYMBOL(dump_stack);
148
149static inline int mask_bits(struct pt_regs *regs, unsigned long bits) 132static inline int mask_bits(struct pt_regs *regs, unsigned long bits)
150{ 133{
151 return (regs->psw.mask & bits) / ((~bits + 1) & bits); 134 return (regs->psw.mask & bits) / ((~bits + 1) & bits);
diff --git a/arch/score/kernel/traps.c b/arch/score/kernel/traps.c
index 0e46fb19a848..a38f435fba7b 100644
--- a/arch/score/kernel/traps.c
+++ b/arch/score/kernel/traps.c
@@ -149,16 +149,6 @@ static void show_registers(struct pt_regs *regs)
149 printk(KERN_NOTICE "\n"); 149 printk(KERN_NOTICE "\n");
150} 150}
151 151
152/*
153 * The architecture-independent dump_stack generator
154 */
155void dump_stack(void)
156{
157 show_stack(current_thread_info()->task,
158 (long *) get_irq_regs()->regs[0]);
159}
160EXPORT_SYMBOL(dump_stack);
161
162void __die(const char *str, struct pt_regs *regs, const char *file, 152void __die(const char *str, struct pt_regs *regs, const char *file,
163 const char *func, unsigned long line) 153 const char *func, unsigned long line)
164{ 154{
diff --git a/arch/sh/kernel/dumpstack.c b/arch/sh/kernel/dumpstack.c
index 7617dc4129ac..b959f5592604 100644
--- a/arch/sh/kernel/dumpstack.c
+++ b/arch/sh/kernel/dumpstack.c
@@ -158,9 +158,3 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
158 (unsigned long)task_stack_page(tsk)); 158 (unsigned long)task_stack_page(tsk));
159 show_trace(tsk, sp, NULL); 159 show_trace(tsk, sp, NULL);
160} 160}
161
162void dump_stack(void)
163{
164 show_stack(NULL, NULL);
165}
166EXPORT_SYMBOL(dump_stack);
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
index 2be4214b3905..dccf5f58d70f 100644
--- a/arch/sparc/kernel/process_32.c
+++ b/arch/sparc/kernel/process_32.c
@@ -164,13 +164,6 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp)
164 printk("\n"); 164 printk("\n");
165} 165}
166 166
167void dump_stack(void)
168{
169 show_stack(current, NULL);
170}
171
172EXPORT_SYMBOL(dump_stack);
173
174/* 167/*
175 * Note: sparc64 has a pretty intricated thread_saved_pc, check it out. 168 * Note: sparc64 has a pretty intricated thread_saved_pc, check it out.
176 */ 169 */
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index 8d38ca97aa23..b3f833ab90eb 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -2350,13 +2350,6 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp)
2350 } while (++count < 16); 2350 } while (++count < 16);
2351} 2351}
2352 2352
2353void dump_stack(void)
2354{
2355 show_stack(current, NULL);
2356}
2357
2358EXPORT_SYMBOL(dump_stack);
2359
2360static inline struct reg_window *kernel_stack_up(struct reg_window *rw) 2353static inline struct reg_window *kernel_stack_up(struct reg_window *rw)
2361{ 2354{
2362 unsigned long fp = rw->ins[6]; 2355 unsigned long fp = rw->ins[6];
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
index e562ff80409a..7d101a2a1541 100644
--- a/arch/um/kernel/sysrq.c
+++ b/arch/um/kernel/sysrq.c
@@ -35,18 +35,6 @@ void show_trace(struct task_struct *task, unsigned long * stack)
35} 35}
36#endif 36#endif
37 37
38/*
39 * stack dumps generator - this is used by arch-independent code.
40 * And this is identical to i386 currently.
41 */
42void dump_stack(void)
43{
44 unsigned long stack;
45
46 show_trace(current, &stack);
47}
48EXPORT_SYMBOL(dump_stack);
49
50/*Stolen from arch/i386/kernel/traps.c */ 38/*Stolen from arch/i386/kernel/traps.c */
51static const int kstack_depth_to_print = 24; 39static const int kstack_depth_to_print = 24;
52 40
diff --git a/arch/unicore32/kernel/traps.c b/arch/unicore32/kernel/traps.c
index 0870b68d2ad9..c54e32410ead 100644
--- a/arch/unicore32/kernel/traps.c
+++ b/arch/unicore32/kernel/traps.c
@@ -170,12 +170,6 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
170 c_backtrace(fp, mode); 170 c_backtrace(fp, mode);
171} 171}
172 172
173void dump_stack(void)
174{
175 dump_backtrace(NULL, NULL);
176}
177EXPORT_SYMBOL(dump_stack);
178
179void show_stack(struct task_struct *tsk, unsigned long *sp) 173void show_stack(struct task_struct *tsk, unsigned long *sp)
180{ 174{
181 dump_backtrace(NULL, tsk); 175 dump_backtrace(NULL, tsk);
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index dd1a7c391c90..deb6421c9e69 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -191,24 +191,6 @@ void show_stack(struct task_struct *task, unsigned long *sp)
191 show_stack_log_lvl(task, NULL, sp, bp, ""); 191 show_stack_log_lvl(task, NULL, sp, bp, "");
192} 192}
193 193
194/*
195 * The architecture-independent dump_stack generator
196 */
197void dump_stack(void)
198{
199 unsigned long bp;
200 unsigned long stack;
201
202 bp = stack_frame(current, NULL);
203 printk("Pid: %d, comm: %.20s %s %s %.*s\n",
204 current->pid, current->comm, print_tainted(),
205 init_utsname()->release,
206 (int)strcspn(init_utsname()->version, " "),
207 init_utsname()->version);
208 show_trace(NULL, NULL, &stack, bp);
209}
210EXPORT_SYMBOL(dump_stack);
211
212static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED; 194static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED;
213static int die_owner = -1; 195static int die_owner = -1;
214static unsigned int die_nest_count; 196static unsigned int die_nest_count;
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index 923db5c15278..384b7c7c2f6d 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -481,14 +481,6 @@ void show_stack(struct task_struct *task, unsigned long *sp)
481 show_trace(task, stack); 481 show_trace(task, stack);
482} 482}
483 483
484void dump_stack(void)
485{
486 show_stack(current, NULL);
487}
488
489EXPORT_SYMBOL(dump_stack);
490
491
492void show_code(unsigned int *pc) 484void show_code(unsigned int *pc)
493{ 485{
494 long i; 486 long i;
diff --git a/include/linux/printk.h b/include/linux/printk.h
index 4890fe62c011..7ce1f878cf6a 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -145,6 +145,7 @@ extern void wake_up_klogd(void);
145 145
146void log_buf_kexec_setup(void); 146void log_buf_kexec_setup(void);
147void __init setup_log_buf(int early); 147void __init setup_log_buf(int early);
148void dump_stack_print_info(const char *log_lvl);
148#else 149#else
149static inline __printf(1, 0) 150static inline __printf(1, 0)
150int vprintk(const char *s, va_list args) 151int vprintk(const char *s, va_list args)
@@ -182,6 +183,10 @@ static inline void log_buf_kexec_setup(void)
182static inline void setup_log_buf(int early) 183static inline void setup_log_buf(int early)
183{ 184{
184} 185}
186
187static inline void dump_stack_print_info(const char *log_lvl)
188{
189}
185#endif 190#endif
186 191
187extern void dump_stack(void) __cold; 192extern void dump_stack(void) __cold;
diff --git a/kernel/printk.c b/kernel/printk.c
index 376914e2869d..70b4b94a0eca 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -43,6 +43,7 @@
43#include <linux/rculist.h> 43#include <linux/rculist.h>
44#include <linux/poll.h> 44#include <linux/poll.h>
45#include <linux/irq_work.h> 45#include <linux/irq_work.h>
46#include <linux/utsname.h>
46 47
47#include <asm/uaccess.h> 48#include <asm/uaccess.h>
48 49
@@ -2849,4 +2850,21 @@ void kmsg_dump_rewind(struct kmsg_dumper *dumper)
2849 raw_spin_unlock_irqrestore(&logbuf_lock, flags); 2850 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
2850} 2851}
2851EXPORT_SYMBOL_GPL(kmsg_dump_rewind); 2852EXPORT_SYMBOL_GPL(kmsg_dump_rewind);
2853
2854/**
2855 * dump_stack_print_info - print generic debug info for dump_stack()
2856 * @log_lvl: log level
2857 *
2858 * Arch-specific dump_stack() implementations can use this function to
2859 * print out the same debug information as the generic dump_stack().
2860 */
2861void dump_stack_print_info(const char *log_lvl)
2862{
2863 printk("%sCPU: %d PID: %d Comm: %.20s %s %s %.*s\n",
2864 log_lvl, raw_smp_processor_id(), current->pid, current->comm,
2865 print_tainted(), init_utsname()->release,
2866 (int)strcspn(init_utsname()->version, " "),
2867 init_utsname()->version);
2868}
2869
2852#endif 2870#endif
diff --git a/lib/dump_stack.c b/lib/dump_stack.c
index 42f4f55c9458..53bad099ebd6 100644
--- a/lib/dump_stack.c
+++ b/lib/dump_stack.c
@@ -5,11 +5,16 @@
5 5
6#include <linux/kernel.h> 6#include <linux/kernel.h>
7#include <linux/export.h> 7#include <linux/export.h>
8#include <linux/sched.h>
8 9
10/**
11 * dump_stack - dump the current task information and its stack trace
12 *
13 * Architectures can override this implementation by implementing its own.
14 */
9void dump_stack(void) 15void dump_stack(void)
10{ 16{
11 printk(KERN_NOTICE 17 dump_stack_print_info(KERN_DEFAULT);
12 "This architecture does not implement dump_stack()\n"); 18 show_stack(NULL, NULL);
13} 19}
14
15EXPORT_SYMBOL(dump_stack); 20EXPORT_SYMBOL(dump_stack);