at v4.12 1.2 kB view raw
1/* 2 * Provide a default dump_stack() function for architectures 3 * which don't implement their own. 4 */ 5 6#include <linux/kernel.h> 7#include <linux/export.h> 8#include <linux/sched.h> 9#include <linux/sched/debug.h> 10#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} 18 19/** 20 * dump_stack - dump the current task information and its stack trace 21 * 22 * Architectures can override this implementation by implementing its own. 23 */ 24#ifdef CONFIG_SMP 25static atomic_t dump_lock = ATOMIC_INIT(-1); 26 27asmlinkage __visible void dump_stack(void) 28{ 29 unsigned long flags; 30 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 */ 38retry: 39 local_irq_save(flags); 40 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 { 47 local_irq_restore(flags); 48 cpu_relax(); 49 goto retry; 50 } 51 52 __dump_stack(); 53 54 if (!was_locked) 55 atomic_set(&dump_lock, -1); 56 57 local_irq_restore(flags); 58} 59#else 60asmlinkage __visible void dump_stack(void) 61{ 62 __dump_stack(); 63} 64#endif 65EXPORT_SYMBOL(dump_stack);