linux/lib/dump_stack.c
<<
>>
Prefs
   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/smp.h>
  10#include <linux/atomic.h>
  11
  12static void __dump_stack(void)
  13{
  14        dump_stack_print_info(KERN_DEFAULT);
  15        show_stack(NULL, NULL);
  16}
  17
  18/**
  19 * dump_stack - dump the current task information and its stack trace
  20 *
  21 * Architectures can override this implementation by implementing its own.
  22 */
  23#ifdef CONFIG_SMP
  24static atomic_t dump_lock = ATOMIC_INIT(-1);
  25
  26asmlinkage __visible void dump_stack(void)
  27{
  28        unsigned long flags;
  29        int was_locked;
  30        int old;
  31        int cpu;
  32
  33        /*
  34         * Permit this cpu to perform nested stack dumps while serialising
  35         * against other CPUs
  36         */
  37retry:
  38        local_irq_save(flags);
  39        cpu = smp_processor_id();
  40        old = atomic_cmpxchg(&dump_lock, -1, cpu);
  41        if (old == -1) {
  42                was_locked = 0;
  43        } else if (old == cpu) {
  44                was_locked = 1;
  45        } else {
  46                local_irq_restore(flags);
  47                cpu_relax();
  48                goto retry;
  49        }
  50
  51        __dump_stack();
  52
  53        if (!was_locked)
  54                atomic_set(&dump_lock, -1);
  55
  56        local_irq_restore(flags);
  57}
  58#else
  59asmlinkage __visible void dump_stack(void)
  60{
  61        __dump_stack();
  62}
  63#endif
  64EXPORT_SYMBOL(dump_stack);
  65