--- zzzz-none-000/linux-3.10.107/lib/dump_stack.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/lib/dump_stack.c 2021-02-04 17:41:59.000000000 +0000 @@ -6,15 +6,59 @@ #include #include #include +#include +#include + +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. */ -void dump_stack(void) +#ifdef CONFIG_SMP +static atomic_t dump_lock = ATOMIC_INIT(-1); + +asmlinkage __visible void dump_stack(void) { - dump_stack_print_info(KERN_DEFAULT); - show_stack(NULL, NULL); + unsigned long flags; + int was_locked; + int old; + int cpu; + + /* + * Permit this cpu to perform nested stack dumps while serialising + * against other CPUs + */ +retry: + local_irq_save(flags); + 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 { + local_irq_restore(flags); + cpu_relax(); + goto retry; + } + + __dump_stack(); + + if (!was_locked) + atomic_set(&dump_lock, -1); + + local_irq_restore(flags); +} +#else +asmlinkage __visible void dump_stack(void) +{ + __dump_stack(); } +#endif EXPORT_SYMBOL(dump_stack);