Commit f92bac3b authored by Sergey Senozhatsky's avatar Sergey Senozhatsky Committed by Petr Mladek

printk: rename nmi.c and exported api

A preparation patch for printk_safe work. No functional change.
- rename nmi.c to print_safe.c
- add `printk_safe' prefix to some (which used both by printk-safe
  and printk-nmi) of the exported functions.

Link: http://lkml.kernel.org/r/20161227141611.940-3-sergey.senozhatsky@gmail.com
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Jan Kara <jack@suse.cz>
Cc: Tejun Heo <tj@kernel.org>
Cc: Calvin Owens <calvinowens@fb.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Peter Hurley <peter@hurleysoftware.com>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: default avatarSergey Senozhatsky <sergey.senozhatsky@gmail.com>
Signed-off-by: default avatarPetr Mladek <pmladek@suse.com>
parent bd66a892
...@@ -147,17 +147,17 @@ void early_printk(const char *s, ...) { } ...@@ -147,17 +147,17 @@ void early_printk(const char *s, ...) { }
#endif #endif
#ifdef CONFIG_PRINTK_NMI #ifdef CONFIG_PRINTK_NMI
extern void printk_nmi_init(void); extern void printk_safe_init(void);
extern void printk_nmi_enter(void); extern void printk_nmi_enter(void);
extern void printk_nmi_exit(void); extern void printk_nmi_exit(void);
extern void printk_nmi_flush(void); extern void printk_safe_flush(void);
extern void printk_nmi_flush_on_panic(void); extern void printk_safe_flush_on_panic(void);
#else #else
static inline void printk_nmi_init(void) { } static inline void printk_safe_init(void) { }
static inline void printk_nmi_enter(void) { } static inline void printk_nmi_enter(void) { }
static inline void printk_nmi_exit(void) { } static inline void printk_nmi_exit(void) { }
static inline void printk_nmi_flush(void) { } static inline void printk_safe_flush(void) { }
static inline void printk_nmi_flush_on_panic(void) { } static inline void printk_safe_flush_on_panic(void) { }
#endif /* PRINTK_NMI */ #endif /* PRINTK_NMI */
#ifdef CONFIG_PRINTK #ifdef CONFIG_PRINTK
......
...@@ -875,17 +875,19 @@ config LOG_CPU_MAX_BUF_SHIFT ...@@ -875,17 +875,19 @@ config LOG_CPU_MAX_BUF_SHIFT
13 => 8 KB for each CPU 13 => 8 KB for each CPU
12 => 4 KB for each CPU 12 => 4 KB for each CPU
config NMI_LOG_BUF_SHIFT config PRINTK_SAFE_LOG_BUF_SHIFT
int "Temporary per-CPU NMI log buffer size (12 => 4KB, 13 => 8KB)" int "Temporary per-CPU printk log buffer size (12 => 4KB, 13 => 8KB)"
range 10 21 range 10 21
default 13 default 13
depends on PRINTK_NMI depends on PRINTK
help help
Select the size of a per-CPU buffer where NMI messages are temporary Select the size of an alternate printk per-CPU buffer where messages
stored. They are copied to the main log buffer in a safe context printed from usafe contexts are temporary stored. One example would
to avoid a deadlock. The value defines the size as a power of 2. be NMI messages, another one - printk recursion. The messages are
copied to the main log buffer in a safe context to avoid a deadlock.
The value defines the size as a power of 2.
NMI messages are rare and limited. The largest one is when Those messages are rare and limited. The largest one is when
a backtrace is printed. It usually fits into 4KB. Select a backtrace is printed. It usually fits into 4KB. Select
8KB if you want to be on the safe side. 8KB if you want to be on the safe side.
......
...@@ -580,7 +580,7 @@ asmlinkage __visible void __init start_kernel(void) ...@@ -580,7 +580,7 @@ asmlinkage __visible void __init start_kernel(void)
timekeeping_init(); timekeeping_init();
time_init(); time_init();
sched_clock_postinit(); sched_clock_postinit();
printk_nmi_init(); printk_safe_init();
perf_event_init(); perf_event_init();
profile_init(); profile_init();
call_function_init(); call_function_init();
......
...@@ -916,7 +916,7 @@ void crash_kexec(struct pt_regs *regs) ...@@ -916,7 +916,7 @@ void crash_kexec(struct pt_regs *regs)
old_cpu = atomic_cmpxchg(&panic_cpu, PANIC_CPU_INVALID, this_cpu); old_cpu = atomic_cmpxchg(&panic_cpu, PANIC_CPU_INVALID, this_cpu);
if (old_cpu == PANIC_CPU_INVALID) { if (old_cpu == PANIC_CPU_INVALID) {
/* This is the 1st CPU which comes here, so go ahead. */ /* This is the 1st CPU which comes here, so go ahead. */
printk_nmi_flush_on_panic(); printk_safe_flush_on_panic();
__crash_kexec(regs); __crash_kexec(regs);
/* /*
......
...@@ -188,7 +188,7 @@ void panic(const char *fmt, ...) ...@@ -188,7 +188,7 @@ void panic(const char *fmt, ...)
* Bypass the panic_cpu check and call __crash_kexec directly. * Bypass the panic_cpu check and call __crash_kexec directly.
*/ */
if (!_crash_kexec_post_notifiers) { if (!_crash_kexec_post_notifiers) {
printk_nmi_flush_on_panic(); printk_safe_flush_on_panic();
__crash_kexec(NULL); __crash_kexec(NULL);
/* /*
...@@ -213,7 +213,7 @@ void panic(const char *fmt, ...) ...@@ -213,7 +213,7 @@ void panic(const char *fmt, ...)
atomic_notifier_call_chain(&panic_notifier_list, 0, buf); atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
/* Call flush even twice. It tries harder with a single online CPU */ /* Call flush even twice. It tries harder with a single online CPU */
printk_nmi_flush_on_panic(); printk_safe_flush_on_panic();
kmsg_dump(KMSG_DUMP_PANIC); kmsg_dump(KMSG_DUMP_PANIC);
/* /*
......
obj-y = printk.o obj-y = printk.o
obj-$(CONFIG_PRINTK_NMI) += nmi.o obj-$(CONFIG_PRINTK_NMI) += printk_safe.o
obj-$(CONFIG_A11Y_BRAILLE_CONSOLE) += braille.o obj-$(CONFIG_A11Y_BRAILLE_CONSOLE) += braille.o
/* /*
* nmi.c - Safe printk in NMI context * printk_safe.c - Safe printk in NMI context
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -39,18 +39,18 @@ ...@@ -39,18 +39,18 @@
* were handled or when IRQs are blocked. * were handled or when IRQs are blocked.
*/ */
DEFINE_PER_CPU(printk_func_t, printk_func) = vprintk_default; DEFINE_PER_CPU(printk_func_t, printk_func) = vprintk_default;
static int printk_nmi_irq_ready; static int printk_safe_irq_ready;
atomic_t nmi_message_lost; atomic_t nmi_message_lost;
#define NMI_LOG_BUF_LEN ((1 << CONFIG_NMI_LOG_BUF_SHIFT) - \ #define SAFE_LOG_BUF_LEN ((1 << CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT) - \
sizeof(atomic_t) - sizeof(struct irq_work)) sizeof(atomic_t) - sizeof(struct irq_work))
struct nmi_seq_buf { struct printk_safe_seq_buf {
atomic_t len; /* length of written data */ atomic_t len; /* length of written data */
struct irq_work work; /* IRQ work that flushes the buffer */ struct irq_work work; /* IRQ work that flushes the buffer */
unsigned char buffer[NMI_LOG_BUF_LEN]; unsigned char buffer[SAFE_LOG_BUF_LEN];
}; };
static DEFINE_PER_CPU(struct nmi_seq_buf, nmi_print_seq); static DEFINE_PER_CPU(struct printk_safe_seq_buf, nmi_print_seq);
/* /*
* Safe printk() for NMI context. It uses a per-CPU buffer to * Safe printk() for NMI context. It uses a per-CPU buffer to
...@@ -60,7 +60,7 @@ static DEFINE_PER_CPU(struct nmi_seq_buf, nmi_print_seq); ...@@ -60,7 +60,7 @@ static DEFINE_PER_CPU(struct nmi_seq_buf, nmi_print_seq);
*/ */
static int vprintk_nmi(const char *fmt, va_list args) static int vprintk_nmi(const char *fmt, va_list args)
{ {
struct nmi_seq_buf *s = this_cpu_ptr(&nmi_print_seq); struct printk_safe_seq_buf *s = this_cpu_ptr(&nmi_print_seq);
int add = 0; int add = 0;
size_t len; size_t len;
...@@ -91,7 +91,7 @@ static int vprintk_nmi(const char *fmt, va_list args) ...@@ -91,7 +91,7 @@ static int vprintk_nmi(const char *fmt, va_list args)
goto again; goto again;
/* Get flushed in a more safe context. */ /* Get flushed in a more safe context. */
if (add && printk_nmi_irq_ready) { if (add && printk_safe_irq_ready) {
/* Make sure that IRQ work is really initialized. */ /* Make sure that IRQ work is really initialized. */
smp_rmb(); smp_rmb();
irq_work_queue(&s->work); irq_work_queue(&s->work);
...@@ -100,7 +100,7 @@ static int vprintk_nmi(const char *fmt, va_list args) ...@@ -100,7 +100,7 @@ static int vprintk_nmi(const char *fmt, va_list args)
return add; return add;
} }
static void printk_nmi_flush_line(const char *text, int len) static void printk_safe_flush_line(const char *text, int len)
{ {
/* /*
* The buffers are flushed in NMI only on panic. The messages must * The buffers are flushed in NMI only on panic. The messages must
...@@ -111,11 +111,10 @@ static void printk_nmi_flush_line(const char *text, int len) ...@@ -111,11 +111,10 @@ static void printk_nmi_flush_line(const char *text, int len)
printk_deferred("%.*s", len, text); printk_deferred("%.*s", len, text);
else else
printk("%.*s", len, text); printk("%.*s", len, text);
} }
/* printk part of the temporary buffer line by line */ /* printk part of the temporary buffer line by line */
static int printk_nmi_flush_buffer(const char *start, size_t len) static int printk_safe_flush_buffer(const char *start, size_t len)
{ {
const char *c, *end; const char *c, *end;
bool header; bool header;
...@@ -127,7 +126,7 @@ static int printk_nmi_flush_buffer(const char *start, size_t len) ...@@ -127,7 +126,7 @@ static int printk_nmi_flush_buffer(const char *start, size_t len)
/* Print line by line. */ /* Print line by line. */
while (c < end) { while (c < end) {
if (*c == '\n') { if (*c == '\n') {
printk_nmi_flush_line(start, c - start + 1); printk_safe_flush_line(start, c - start + 1);
start = ++c; start = ++c;
header = true; header = true;
continue; continue;
...@@ -140,7 +139,7 @@ static int printk_nmi_flush_buffer(const char *start, size_t len) ...@@ -140,7 +139,7 @@ static int printk_nmi_flush_buffer(const char *start, size_t len)
continue; continue;
} }
printk_nmi_flush_line(start, c - start); printk_safe_flush_line(start, c - start);
start = c++; start = c++;
header = true; header = true;
continue; continue;
...@@ -154,8 +153,8 @@ static int printk_nmi_flush_buffer(const char *start, size_t len) ...@@ -154,8 +153,8 @@ static int printk_nmi_flush_buffer(const char *start, size_t len)
if (start < end && !header) { if (start < end && !header) {
static const char newline[] = KERN_CONT "\n"; static const char newline[] = KERN_CONT "\n";
printk_nmi_flush_line(start, end - start); printk_safe_flush_line(start, end - start);
printk_nmi_flush_line(newline, strlen(newline)); printk_safe_flush_line(newline, strlen(newline));
} }
return len; return len;
...@@ -165,11 +164,12 @@ static int printk_nmi_flush_buffer(const char *start, size_t len) ...@@ -165,11 +164,12 @@ static int printk_nmi_flush_buffer(const char *start, size_t len)
* Flush data from the associated per_CPU buffer. The function * Flush data from the associated per_CPU buffer. The function
* can be called either via IRQ work or independently. * can be called either via IRQ work or independently.
*/ */
static void __printk_nmi_flush(struct irq_work *work) static void __printk_safe_flush(struct irq_work *work)
{ {
static raw_spinlock_t read_lock = static raw_spinlock_t read_lock =
__RAW_SPIN_LOCK_INITIALIZER(read_lock); __RAW_SPIN_LOCK_INITIALIZER(read_lock);
struct nmi_seq_buf *s = container_of(work, struct nmi_seq_buf, work); struct printk_safe_seq_buf *s =
container_of(work, struct printk_safe_seq_buf, work);
unsigned long flags; unsigned long flags;
size_t len; size_t len;
int i; int i;
...@@ -194,9 +194,9 @@ static void __printk_nmi_flush(struct irq_work *work) ...@@ -194,9 +194,9 @@ static void __printk_nmi_flush(struct irq_work *work)
* buffer size. * buffer size.
*/ */
if ((i && i >= len) || len > sizeof(s->buffer)) { if ((i && i >= len) || len > sizeof(s->buffer)) {
const char *msg = "printk_nmi_flush: internal error\n"; const char *msg = "printk_safe_flush: internal error\n";
printk_nmi_flush_line(msg, strlen(msg)); printk_safe_flush_line(msg, strlen(msg));
len = 0; len = 0;
} }
...@@ -205,7 +205,7 @@ static void __printk_nmi_flush(struct irq_work *work) ...@@ -205,7 +205,7 @@ static void __printk_nmi_flush(struct irq_work *work)
/* Make sure that data has been written up to the @len */ /* Make sure that data has been written up to the @len */
smp_rmb(); smp_rmb();
i += printk_nmi_flush_buffer(s->buffer + i, len - i); i += printk_safe_flush_buffer(s->buffer + i, len - i);
/* /*
* Check that nothing has got added in the meantime and truncate * Check that nothing has got added in the meantime and truncate
...@@ -221,31 +221,31 @@ static void __printk_nmi_flush(struct irq_work *work) ...@@ -221,31 +221,31 @@ static void __printk_nmi_flush(struct irq_work *work)
} }
/** /**
* printk_nmi_flush - flush all per-cpu nmi buffers. * printk_safe_flush - flush all per-cpu nmi buffers.
* *
* The buffers are flushed automatically via IRQ work. This function * The buffers are flushed automatically via IRQ work. This function
* is useful only when someone wants to be sure that all buffers have * is useful only when someone wants to be sure that all buffers have
* been flushed at some point. * been flushed at some point.
*/ */
void printk_nmi_flush(void) void printk_safe_flush(void)
{ {
int cpu; int cpu;
for_each_possible_cpu(cpu) for_each_possible_cpu(cpu)
__printk_nmi_flush(&per_cpu(nmi_print_seq, cpu).work); __printk_safe_flush(&per_cpu(nmi_print_seq, cpu).work);
} }
/** /**
* printk_nmi_flush_on_panic - flush all per-cpu nmi buffers when the system * printk_safe_flush_on_panic - flush all per-cpu nmi buffers when the system
* goes down. * goes down.
* *
* Similar to printk_nmi_flush() but it can be called even in NMI context when * Similar to printk_safe_flush() but it can be called even in NMI context when
* the system goes down. It does the best effort to get NMI messages into * the system goes down. It does the best effort to get NMI messages into
* the main ring buffer. * the main ring buffer.
* *
* Note that it could try harder when there is only one CPU online. * Note that it could try harder when there is only one CPU online.
*/ */
void printk_nmi_flush_on_panic(void) void printk_safe_flush_on_panic(void)
{ {
/* /*
* Make sure that we could access the main ring buffer. * Make sure that we could access the main ring buffer.
...@@ -259,25 +259,25 @@ void printk_nmi_flush_on_panic(void) ...@@ -259,25 +259,25 @@ void printk_nmi_flush_on_panic(void)
raw_spin_lock_init(&logbuf_lock); raw_spin_lock_init(&logbuf_lock);
} }
printk_nmi_flush(); printk_safe_flush();
} }
void __init printk_nmi_init(void) void __init printk_safe_init(void)
{ {
int cpu; int cpu;
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
struct nmi_seq_buf *s = &per_cpu(nmi_print_seq, cpu); struct printk_safe_seq_buf *s = &per_cpu(nmi_print_seq, cpu);
init_irq_work(&s->work, __printk_nmi_flush); init_irq_work(&s->work, __printk_safe_flush);
} }
/* Make sure that IRQ works are initialized before enabling. */ /* Make sure that IRQ works are initialized before enabling. */
smp_wmb(); smp_wmb();
printk_nmi_irq_ready = 1; printk_safe_irq_ready = 1;
/* Flush pending messages that did not have scheduled IRQ works. */ /* Flush pending messages that did not have scheduled IRQ works. */
printk_nmi_flush(); printk_safe_flush();
} }
void printk_nmi_enter(void) void printk_nmi_enter(void)
......
...@@ -77,7 +77,7 @@ void nmi_trigger_cpumask_backtrace(const cpumask_t *mask, ...@@ -77,7 +77,7 @@ void nmi_trigger_cpumask_backtrace(const cpumask_t *mask,
* Force flush any remote buffers that might be stuck in IRQ context * Force flush any remote buffers that might be stuck in IRQ context
* and therefore could not run their irq_work. * and therefore could not run their irq_work.
*/ */
printk_nmi_flush(); printk_safe_flush();
clear_bit_unlock(0, &backtrace_flag); clear_bit_unlock(0, &backtrace_flag);
put_cpu(); put_cpu();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment