/* * Provide a default dump_stack() function for architectures * which don't implement their own. */ #include <linux/kernel.h> #include <linux/export.h> #include <linux/sched.h> #include <linux/smp.h> #include <linux/atomic.h> static void __dump_stack(void) { dump_stack_print_info(KERN_DEFAULT); show_stack(NULL, NULL); } /** * dump_stack - dump the current task information and its stack trace * * Architectures can override this implementation by implementing its own. */ #ifdef CONFIG_SMP static atomic_t dump_lock = ATOMIC_INIT(-1); asmlinkage void dump_stack(void) { int was_locked; int old; int cpu; /* * Permit this cpu to perform nested stack dumps while serialising * against other CPUs */ preempt_disable(); retry: cpu = smp_processor_id(); old = atomic_cmpxchg(&dump_lock, -1, cpu); if (old == -1) { was_locked = 0; } else if (old == cpu) { was_locked = 1; } else { cpu_relax(); goto retry; } __dump_stack(); if (!was_locked) atomic_set(&dump_lock, -1); preempt_enable(); } #else asmlinkage void dump_stack(void) { __dump_stack(); } #endif EXPORT_SYMBOL(dump_stack);