aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPetr Mladek <pmladek@suse.com>2016-05-20 20:00:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-20 20:58:30 -0400
commit42a0bb3f71383b457a7db362f1c69e7afb96732b (patch)
treec63f12bed74fee20662fbcc8cc985d53a0d20def /lib
parent2eeed7e98d6a1341b1574893a95ce5b8379140f2 (diff)
printk/nmi: generic solution for safe printk in NMI
printk() takes some locks and could not be used a safe way in NMI context. The chance of a deadlock is real especially when printing stacks from all CPUs. This particular problem has been addressed on x86 by the commit a9edc8809328 ("x86/nmi: Perform a safe NMI stack trace on all CPUs"). The patchset brings two big advantages. First, it makes the NMI backtraces safe on all architectures for free. Second, it makes all NMI messages almost safe on all architectures (the temporary buffer is limited. We still should keep the number of messages in NMI context at minimum). Note that there already are several messages printed in NMI context: WARN_ON(in_nmi()), BUG_ON(in_nmi()), anything being printed out from MCE handlers. These are not easy to avoid. This patch reuses most of the code and makes it generic. It is useful for all messages and architectures that support NMI. The alternative printk_func is set when entering and is reseted when leaving NMI context. It queues IRQ work to copy the messages into the main ring buffer in a safe context. __printk_nmi_flush() copies all available messages and reset the buffer. Then we could use a simple cmpxchg operations to get synchronized with writers. There is also used a spinlock to get synchronized with other flushers. We do not longer use seq_buf because it depends on external lock. It would be hard to make all supported operations safe for a lockless use. It would be confusing and error prone to make only some operations safe. The code is put into separate printk/nmi.c as suggested by Steven Rostedt. It needs a per-CPU buffer and is compiled only on architectures that call nmi_enter(). This is achieved by the new HAVE_NMI Kconfig flag. The are MN10300 and Xtensa architectures. We need to clean up NMI handling there first. Let's do it separately. The patch is heavily based on the draft from Peter Zijlstra, see https://lkml.org/lkml/2015/6/10/327 [arnd@arndb.de: printk-nmi: use %zu format string for size_t] [akpm@linux-foundation.org: min_t->min - all types are size_t here] Signed-off-by: Petr Mladek <pmladek@suse.com> Suggested-by: Peter Zijlstra <peterz@infradead.org> Suggested-by: Steven Rostedt <rostedt@goodmis.org> Cc: Jan Kara <jack@suse.cz> Acked-by: Russell King <rmk+kernel@arm.linux.org.uk> [arm part] Cc: Daniel Thompson <daniel.thompson@linaro.org> Cc: Jiri Kosina <jkosina@suse.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: David Miller <davem@davemloft.net> Cc: Daniel Thompson <daniel.thompson@linaro.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/nmi_backtrace.c89
1 files changed, 5 insertions, 84 deletions
diff --git a/lib/nmi_backtrace.c b/lib/nmi_backtrace.c
index 6019c53c669e..26caf51cc238 100644
--- a/lib/nmi_backtrace.c
+++ b/lib/nmi_backtrace.c
@@ -16,33 +16,14 @@
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/kprobes.h> 17#include <linux/kprobes.h>
18#include <linux/nmi.h> 18#include <linux/nmi.h>
19#include <linux/seq_buf.h>
20 19
21#ifdef arch_trigger_all_cpu_backtrace 20#ifdef arch_trigger_all_cpu_backtrace
22/* For reliability, we're prepared to waste bits here. */ 21/* For reliability, we're prepared to waste bits here. */
23static DECLARE_BITMAP(backtrace_mask, NR_CPUS) __read_mostly; 22static DECLARE_BITMAP(backtrace_mask, NR_CPUS) __read_mostly;
24static cpumask_t printtrace_mask;
25
26#define NMI_BUF_SIZE 4096
27
28struct nmi_seq_buf {
29 unsigned char buffer[NMI_BUF_SIZE];
30 struct seq_buf seq;
31};
32
33/* Safe printing in NMI context */
34static DEFINE_PER_CPU(struct nmi_seq_buf, nmi_print_seq);
35 23
36/* "in progress" flag of arch_trigger_all_cpu_backtrace */ 24/* "in progress" flag of arch_trigger_all_cpu_backtrace */
37static unsigned long backtrace_flag; 25static unsigned long backtrace_flag;
38 26
39static void print_seq_line(struct nmi_seq_buf *s, int start, int end)
40{
41 const char *buf = s->buffer + start;
42
43 printk("%.*s", (end - start) + 1, buf);
44}
45
46/* 27/*
47 * When raise() is called it will be is passed a pointer to the 28 * When raise() is called it will be is passed a pointer to the
48 * backtrace_mask. Architectures that call nmi_cpu_backtrace() 29 * backtrace_mask. Architectures that call nmi_cpu_backtrace()
@@ -52,8 +33,7 @@ static void print_seq_line(struct nmi_seq_buf *s, int start, int end)
52void nmi_trigger_all_cpu_backtrace(bool include_self, 33void nmi_trigger_all_cpu_backtrace(bool include_self,
53 void (*raise)(cpumask_t *mask)) 34 void (*raise)(cpumask_t *mask))
54{ 35{
55 struct nmi_seq_buf *s; 36 int i, this_cpu = get_cpu();
56 int i, cpu, this_cpu = get_cpu();
57 37
58 if (test_and_set_bit(0, &backtrace_flag)) { 38 if (test_and_set_bit(0, &backtrace_flag)) {
59 /* 39 /*
@@ -68,17 +48,6 @@ void nmi_trigger_all_cpu_backtrace(bool include_self,
68 if (!include_self) 48 if (!include_self)
69 cpumask_clear_cpu(this_cpu, to_cpumask(backtrace_mask)); 49 cpumask_clear_cpu(this_cpu, to_cpumask(backtrace_mask));
70 50
71 cpumask_copy(&printtrace_mask, to_cpumask(backtrace_mask));
72
73 /*
74 * Set up per_cpu seq_buf buffers that the NMIs running on the other
75 * CPUs will write to.
76 */
77 for_each_cpu(cpu, to_cpumask(backtrace_mask)) {
78 s = &per_cpu(nmi_print_seq, cpu);
79 seq_buf_init(&s->seq, s->buffer, NMI_BUF_SIZE);
80 }
81
82 if (!cpumask_empty(to_cpumask(backtrace_mask))) { 51 if (!cpumask_empty(to_cpumask(backtrace_mask))) {
83 pr_info("Sending NMI to %s CPUs:\n", 52 pr_info("Sending NMI to %s CPUs:\n",
84 (include_self ? "all" : "other")); 53 (include_self ? "all" : "other"));
@@ -94,73 +63,25 @@ void nmi_trigger_all_cpu_backtrace(bool include_self,
94 } 63 }
95 64
96 /* 65 /*
97 * Now that all the NMIs have triggered, we can dump out their 66 * Force flush any remote buffers that might be stuck in IRQ context
98 * back traces safely to the console. 67 * and therefore could not run their irq_work.
99 */ 68 */
100 for_each_cpu(cpu, &printtrace_mask) { 69 printk_nmi_flush();
101 int len, last_i = 0;
102 70
103 s = &per_cpu(nmi_print_seq, cpu); 71 clear_bit_unlock(0, &backtrace_flag);
104 len = seq_buf_used(&s->seq);
105 if (!len)
106 continue;
107
108 /* Print line by line. */
109 for (i = 0; i < len; i++) {
110 if (s->buffer[i] == '\n') {
111 print_seq_line(s, last_i, i);
112 last_i = i + 1;
113 }
114 }
115 /* Check if there was a partial line. */
116 if (last_i < len) {
117 print_seq_line(s, last_i, len - 1);
118 pr_cont("\n");
119 }
120 }
121
122 clear_bit(0, &backtrace_flag);
123 smp_mb__after_atomic();
124 put_cpu(); 72 put_cpu();
125} 73}
126 74
127/*
128 * It is not safe to call printk() directly from NMI handlers.
129 * It may be fine if the NMI detected a lock up and we have no choice
130 * but to do so, but doing a NMI on all other CPUs to get a back trace
131 * can be done with a sysrq-l. We don't want that to lock up, which
132 * can happen if the NMI interrupts a printk in progress.
133 *
134 * Instead, we redirect the vprintk() to this nmi_vprintk() that writes
135 * the content into a per cpu seq_buf buffer. Then when the NMIs are
136 * all done, we can safely dump the contents of the seq_buf to a printk()
137 * from a non NMI context.
138 */
139static int nmi_vprintk(const char *fmt, va_list args)
140{
141 struct nmi_seq_buf *s = this_cpu_ptr(&nmi_print_seq);
142 unsigned int len = seq_buf_used(&s->seq);
143
144 seq_buf_vprintf(&s->seq, fmt, args);
145 return seq_buf_used(&s->seq) - len;
146}
147
148bool nmi_cpu_backtrace(struct pt_regs *regs) 75bool nmi_cpu_backtrace(struct pt_regs *regs)
149{ 76{
150 int cpu = smp_processor_id(); 77 int cpu = smp_processor_id();
151 78
152 if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) { 79 if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) {
153 printk_func_t printk_func_save = this_cpu_read(printk_func);
154
155 /* Replace printk to write into the NMI seq */
156 this_cpu_write(printk_func, nmi_vprintk);
157 pr_warn("NMI backtrace for cpu %d\n", cpu); 80 pr_warn("NMI backtrace for cpu %d\n", cpu);
158 if (regs) 81 if (regs)
159 show_regs(regs); 82 show_regs(regs);
160 else 83 else
161 dump_stack(); 84 dump_stack();
162 this_cpu_write(printk_func, printk_func_save);
163
164 cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask)); 85 cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));
165 return true; 86 return true;
166 } 87 }