b24413180f560 (Greg Kroah-Hartman 2017-11-01 15:07:57 +0100 1) // SPDX-License-Identifier: GPL-2.0
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3) * Provide a default dump_stack() function for architectures
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 4) * which don't implement their own.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 5) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 6)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 7) #include <linux/kernel.h>
8bc3bcc93a2b4 (Paul Gortmaker 2011-11-16 21:29:17 -0500 8) #include <linux/export.h>
196779b9b4ce1 (Tejun Heo 2013-04-30 15:27:12 -0700 9) #include <linux/sched.h>
b17b01533b719 (Ingo Molnar 2017-02-08 18:51:35 +0100 10) #include <linux/sched/debug.h>
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 11) #include <linux/smp.h>
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 12) #include <linux/atomic.h>
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 13) #include <linux/kexec.h>
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 14) #include <linux/utsname.h>
a8b62fd085050 (Peter Zijlstra 2020-09-21 12:58:17 +0200 15) #include <linux/stop_machine.h>
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 16)
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 17) static char dump_stack_arch_desc_str[128];
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 18)
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 19) /**
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 20) * dump_stack_set_arch_desc - set arch-specific str to show with task dumps
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 21) * @fmt: printf-style format string
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 22) * @...: arguments for the format string
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 23) *
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 24) * The configured string will be printed right after utsname during task
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 25) * dumps. Usually used to add arch-specific system identifiers. If an
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 26) * arch wants to make use of such an ID string, it should initialize this
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 27) * as soon as possible during boot.
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 28) */
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 29) void __init dump_stack_set_arch_desc(const char *fmt, ...)
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 30) {
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 31) va_list args;
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 32)
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 33) va_start(args, fmt);
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 34) vsnprintf(dump_stack_arch_desc_str, sizeof(dump_stack_arch_desc_str),
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 35) fmt, args);
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 36) va_end(args);
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 37) }
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 38)
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 39) /**
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 40) * dump_stack_print_info - print generic debug info for dump_stack()
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 41) * @log_lvl: log level
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 42) *
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 43) * Arch-specific dump_stack() implementations can use this function to
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 44) * print out the same debug information as the generic dump_stack().
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 45) */
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 46) void dump_stack_print_info(const char *log_lvl)
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 47) {
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 48) printk("%sCPU: %d PID: %d Comm: %.20s %s%s %s %.*s\n",
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 49) log_lvl, raw_smp_processor_id(), current->pid, current->comm,
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 50) kexec_crash_loaded() ? "Kdump: loaded " : "",
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 51) print_tainted(),
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 52) init_utsname()->release,
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 53) (int)strcspn(init_utsname()->version, " "),
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 54) init_utsname()->version);
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 55)
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 56) if (dump_stack_arch_desc_str[0] != '\0')
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 57) printk("%sHardware name: %s\n",
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 58) log_lvl, dump_stack_arch_desc_str);
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 59)
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 60) print_worker_info(log_lvl, current);
a8b62fd085050 (Peter Zijlstra 2020-09-21 12:58:17 +0200 61) print_stop_info(log_lvl, current);
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 62) }
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 63)
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 64) /**
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 65) * show_regs_print_info - print generic debug info for show_regs()
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 66) * @log_lvl: log level
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 67) *
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 68) * show_regs() implementations can use this function to print out generic
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 69) * debug information.
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 70) */
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 71) void show_regs_print_info(const char *log_lvl)
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 72) {
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 73) dump_stack_print_info(log_lvl);
e36df28f532f8 (Dave Young 2018-02-13 15:28:34 +0800 74) }
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 75)
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 76) static void __dump_stack(void)
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 77) {
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 78) dump_stack_print_info(KERN_DEFAULT);
9cb8f069deeed (Dmitry Safonov 2020-06-08 21:32:29 -0700 79) show_stack(NULL, NULL, KERN_DEFAULT);
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 80) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 81)
196779b9b4ce1 (Tejun Heo 2013-04-30 15:27:12 -0700 82) /**
196779b9b4ce1 (Tejun Heo 2013-04-30 15:27:12 -0700 83) * dump_stack - dump the current task information and its stack trace
196779b9b4ce1 (Tejun Heo 2013-04-30 15:27:12 -0700 84) *
196779b9b4ce1 (Tejun Heo 2013-04-30 15:27:12 -0700 85) * Architectures can override this implementation by implementing its own.
196779b9b4ce1 (Tejun Heo 2013-04-30 15:27:12 -0700 86) */
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 87) #ifdef CONFIG_SMP
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 88) static atomic_t dump_lock = ATOMIC_INIT(-1);
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 89)
722a9f9299ca7 (Andi Kleen 2014-05-02 00:44:38 +0200 90) asmlinkage __visible void dump_stack(void)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 91) {
d7ce36924344a (Eric Dumazet 2016-02-05 15:36:16 -0800 92) unsigned long flags;
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 93) int was_locked;
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 94) int old;
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 95) int cpu;
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 96)
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 97) /*
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 98) * Permit this cpu to perform nested stack dumps while serialising
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 99) * against other CPUs
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 100) */
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 101) retry:
d7ce36924344a (Eric Dumazet 2016-02-05 15:36:16 -0800 102) local_irq_save(flags);
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 103) cpu = smp_processor_id();
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 104) old = atomic_cmpxchg(&dump_lock, -1, cpu);
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 105) if (old == -1) {
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 106) was_locked = 0;
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 107) } else if (old == cpu) {
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 108) was_locked = 1;
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 109) } else {
d7ce36924344a (Eric Dumazet 2016-02-05 15:36:16 -0800 110) local_irq_restore(flags);
5cbf2fff3bba8 (Kevin Hao 2019-11-05 21:16:57 -0800 111) /*
5cbf2fff3bba8 (Kevin Hao 2019-11-05 21:16:57 -0800 112) * Wait for the lock to release before jumping to
5cbf2fff3bba8 (Kevin Hao 2019-11-05 21:16:57 -0800 113) * atomic_cmpxchg() in order to mitigate the thundering herd
5cbf2fff3bba8 (Kevin Hao 2019-11-05 21:16:57 -0800 114) * problem.
5cbf2fff3bba8 (Kevin Hao 2019-11-05 21:16:57 -0800 115) */
5cbf2fff3bba8 (Kevin Hao 2019-11-05 21:16:57 -0800 116) do { cpu_relax(); } while (atomic_read(&dump_lock) != -1);
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 117) goto retry;
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 118) }
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 119)
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 120) __dump_stack();
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 121)
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 122) if (!was_locked)
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 123) atomic_set(&dump_lock, -1);
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 124)
d7ce36924344a (Eric Dumazet 2016-02-05 15:36:16 -0800 125) local_irq_restore(flags);
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 126) }
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 127) #else
722a9f9299ca7 (Andi Kleen 2014-05-02 00:44:38 +0200 128) asmlinkage __visible void dump_stack(void)
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 129) {
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 130) __dump_stack();
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 131) }
b58d977432c80 (Alex Thorlton 2013-07-03 15:04:59 -0700 132) #endif
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 133) EXPORT_SYMBOL(dump_stack);