]>
Commit | Line | Data |
---|---|---|
1ccea77e | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
42a0bb3f | 2 | /* |
099f1c84 | 3 | * printk_safe.c - Safe printk for printk-deadlock-prone contexts |
42a0bb3f PM |
4 | */ |
5 | ||
6 | #include <linux/preempt.h> | |
2a9e5ded | 7 | #include <linux/kdb.h> |
42a0bb3f PM |
8 | #include <linux/smp.h> |
9 | #include <linux/cpumask.h> | |
42a0bb3f | 10 | #include <linux/printk.h> |
b0f51883 | 11 | #include <linux/kprobes.h> |
42a0bb3f PM |
12 | |
13 | #include "internal.h" | |
14 | ||
099f1c84 SS |
15 | static DEFINE_PER_CPU(int, printk_context); |
16 | ||
099f1c84 SS |
17 | /* Can be preempted by NMI. */ |
18 | void __printk_safe_enter(void) | |
19 | { | |
20 | this_cpu_inc(printk_context); | |
21 | } | |
22 | ||
23 | /* Can be preempted by NMI. */ | |
24 | void __printk_safe_exit(void) | |
25 | { | |
26 | this_cpu_dec(printk_context); | |
27 | } | |
28 | ||
28e1745b | 29 | asmlinkage int vprintk(const char *fmt, va_list args) |
099f1c84 | 30 | { |
2a9e5ded PM |
31 | #ifdef CONFIG_KGDB_KDB |
32 | /* Allow to pass printk() to kdb but avoid a recursion. */ | |
33 | if (unlikely(kdb_trap_printk && kdb_printf_cpu < 0)) | |
34 | return vkdb_printf(KDB_MSGSRC_PRINTK, fmt, args); | |
35 | #endif | |
36 | ||
03fc7f9c | 37 | /* |
996e9666 | 38 | * Use the main logbuf even in NMI. But avoid calling console |
03fc7f9c PM |
39 | * drivers that might have their own locks. |
40 | */ | |
696ffaf5 JO |
41 | if (this_cpu_read(printk_context) || in_nmi()) |
42 | return vprintk_deferred(fmt, args); | |
03fc7f9c | 43 | |
719f6a70 | 44 | /* No obstacles. */ |
099f1c84 SS |
45 | return vprintk_default(fmt, args); |
46 | } | |
6262e1b9 | 47 | EXPORT_SYMBOL(vprintk); |