LCOV - code coverage report
Current view: top level - lib - dump_stack.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 11 41 26.8 %
Date: 2021-04-22 12:43:58 Functions: 2 5 40.0 %

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

Generated by: LCOV version 1.14