From: Alex Thorlton Date: Wed, 3 Jul 2013 22:04:59 +0000 (-0700) Subject: dump_stack: serialize the output from dump_stack() X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=b58d977432c80ee60d6970042775a62e3f8d7675;p=GitHub%2Fexynos8895%2Fandroid_kernel_samsung_universal8895.git dump_stack: serialize the output from dump_stack() Add functionality to serialize the output from dump_stack() to avoid mangling of the output when dump_stack is called simultaneously from multiple cpus. [akpm@linux-foundation.org: fix comment indenting, avoid inclusion of files - use where possiblem fix uniprocessor build (__dump_stack undefined), remove unneeded ifdef around smp.h inclusion] Signed-off-by: Alex Thorlton Reported-by: Russ Anderson Reviewed-by: Robin Holt Cc: Vineet Gupta Cc: David S. Miller Cc: Richard Kuo Cc: Jesper Nilsson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- diff --git a/lib/dump_stack.c b/lib/dump_stack.c index 53bad099ebd6..c03154173cc7 100644 --- a/lib/dump_stack.c +++ b/lib/dump_stack.c @@ -6,15 +6,58 @@ #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. */ +#ifdef CONFIG_SMP +static atomic_t dump_lock = ATOMIC_INIT(-1); + void dump_stack(void) { - dump_stack_print_info(KERN_DEFAULT); - show_stack(NULL, NULL); + 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 +void dump_stack(void) +{ + __dump_stack(); } +#endif EXPORT_SYMBOL(dump_stack);