blob: 625375e7f11f98f2468002772265e30e753345fb [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Provide a default dump_stack() function for architectures
3 * which don't implement their own.
4 */
5
6#include <linux/kernel.h>
Paul Gortmaker8bc3bcc2011-11-16 21:29:17 -05007#include <linux/export.h>
Tejun Heo196779b2013-04-30 15:27:12 -07008#include <linux/sched.h>
Ingo Molnarb17b0152017-02-08 18:51:35 +01009#include <linux/sched/debug.h>
Alex Thorltonb58d9772013-07-03 15:04:59 -070010#include <linux/smp.h>
11#include <linux/atomic.h>
12
13static void __dump_stack(void)
14{
15 dump_stack_print_info(KERN_DEFAULT);
16 show_stack(NULL, NULL);
17}
Linus Torvalds1da177e2005-04-16 15:20:36 -070018
Tejun Heo196779b2013-04-30 15:27:12 -070019/**
20 * dump_stack - dump the current task information and its stack trace
21 *
22 * Architectures can override this implementation by implementing its own.
23 */
Alex Thorltonb58d9772013-07-03 15:04:59 -070024#ifdef CONFIG_SMP
25static atomic_t dump_lock = ATOMIC_INIT(-1);
26
Andi Kleen722a9f92014-05-02 00:44:38 +020027asmlinkage __visible void dump_stack(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -070028{
Eric Dumazetd7ce3692016-02-05 15:36:16 -080029 unsigned long flags;
Alex Thorltonb58d9772013-07-03 15:04:59 -070030 int was_locked;
31 int old;
32 int cpu;
33
34 /*
35 * Permit this cpu to perform nested stack dumps while serialising
36 * against other CPUs
37 */
Alex Thorltonb58d9772013-07-03 15:04:59 -070038retry:
Eric Dumazetd7ce3692016-02-05 15:36:16 -080039 local_irq_save(flags);
Alex Thorltonb58d9772013-07-03 15:04:59 -070040 cpu = smp_processor_id();
41 old = atomic_cmpxchg(&dump_lock, -1, cpu);
42 if (old == -1) {
43 was_locked = 0;
44 } else if (old == cpu) {
45 was_locked = 1;
46 } else {
Eric Dumazetd7ce3692016-02-05 15:36:16 -080047 local_irq_restore(flags);
Alex Thorltonb58d9772013-07-03 15:04:59 -070048 cpu_relax();
49 goto retry;
50 }
51
52 __dump_stack();
53
54 if (!was_locked)
55 atomic_set(&dump_lock, -1);
56
Eric Dumazetd7ce3692016-02-05 15:36:16 -080057 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -070058}
Alex Thorltonb58d9772013-07-03 15:04:59 -070059#else
Andi Kleen722a9f92014-05-02 00:44:38 +020060asmlinkage __visible void dump_stack(void)
Alex Thorltonb58d9772013-07-03 15:04:59 -070061{
62 __dump_stack();
63}
64#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070065EXPORT_SYMBOL(dump_stack);