dump_stack.c 1.1 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6
/*
 * Provide a default dump_stack() function for architectures
 * which don't implement their own.
 */

#include <linux/kernel.h>
7
#include <linux/export.h>
8
#include <linux/sched.h>
9 10 11 12 13 14 15 16
#include <linux/smp.h>
#include <linux/atomic.h>

static void __dump_stack(void)
{
	dump_stack_print_info(KERN_DEFAULT);
	show_stack(NULL, NULL);
}
L
Linus Torvalds 已提交
17

18 19 20 21 22
/**
 * dump_stack - dump the current task information and its stack trace
 *
 * Architectures can override this implementation by implementing its own.
 */
23 24 25
#ifdef CONFIG_SMP
static atomic_t dump_lock = ATOMIC_INIT(-1);

26
asmlinkage __visible void dump_stack(void)
L
Linus Torvalds 已提交
27
{
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
	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
58
asmlinkage __visible void dump_stack(void)
59 60
{
	__dump_stack();
L
Linus Torvalds 已提交
61
}
62
#endif
L
Linus Torvalds 已提交
63
EXPORT_SYMBOL(dump_stack);