aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/printk.h
diff options
context:
space:
mode:
authorJohn Ogness <john.ogness@linutronix.de>2021-06-17 11:56:50 +0206
committerPetr Mladek <pmladek@suse.com>2021-06-22 09:56:10 +0200
commit766c268bc6d39b8124e50d075a36b8a3305bc8e2 (patch)
treedafc8ab972a947740d23a339be866378bd7902dc /include/linux/printk.h
parentkernel/printk.c: Fixed mundane typos (diff)
downloadlinux-dev-766c268bc6d39b8124e50d075a36b8a3305bc8e2.tar.xz
linux-dev-766c268bc6d39b8124e50d075a36b8a3305bc8e2.zip
lib/dump_stack: move cpu lock to printk.c
dump_stack() implements its own cpu-reentrant spinning lock to best-effort serialize stack traces in the printk log. However, there are other functions (such as show_regs()) that can also benefit from this serialization. Move the cpu-reentrant spinning lock (cpu lock) into new helper functions printk_cpu_lock_irqsave()/printk_cpu_unlock_irqrestore() so that it is available for others as well. For !CONFIG_SMP the cpu lock is a NOP. Note that having multiple cpu locks in the system can easily lead to deadlock. Code needing a cpu lock should use the printk cpu lock, since the printk cpu lock could be acquired from any code and any context. Also note that it is not necessary for a cpu lock to disable interrupts. However, in upcoming work this cpu lock will be used for emergency tasks (for example, atomic consoles during kernel crashes) and any interruptions while holding the cpu lock should be avoided if possible. Signed-off-by: John Ogness <john.ogness@linutronix.de> Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org> Reviewed-by: Petr Mladek <pmladek@suse.com> [pmladek@suse.com: Backported on top of 5.13-rc1.] Signed-off-by: Petr Mladek <pmladek@suse.com> Link: https://lore.kernel.org/r/20210617095051.4808-2-john.ogness@linutronix.de
Diffstat (limited to 'include/linux/printk.h')
-rw-r--r--include/linux/printk.h41
1 files changed, 41 insertions, 0 deletions
diff --git a/include/linux/printk.h b/include/linux/printk.h
index fe7eb2351610..1790a5521fd9 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -282,6 +282,47 @@ static inline void printk_safe_flush_on_panic(void)
}
#endif
+#ifdef CONFIG_SMP
+extern int __printk_cpu_trylock(void);
+extern void __printk_wait_on_cpu_lock(void);
+extern void __printk_cpu_unlock(void);
+
+/**
+ * printk_cpu_lock_irqsave() - Acquire the printk cpu-reentrant spinning
+ * lock and disable interrupts.
+ * @flags: Stack-allocated storage for saving local interrupt state,
+ * to be passed to printk_cpu_unlock_irqrestore().
+ *
+ * If the lock is owned by another CPU, spin until it becomes available.
+ * Interrupts are restored while spinning.
+ */
+#define printk_cpu_lock_irqsave(flags) \
+ for (;;) { \
+ local_irq_save(flags); \
+ if (__printk_cpu_trylock()) \
+ break; \
+ local_irq_restore(flags); \
+ __printk_wait_on_cpu_lock(); \
+ }
+
+/**
+ * printk_cpu_unlock_irqrestore() - Release the printk cpu-reentrant spinning
+ * lock and restore interrupts.
+ * @flags: Caller's saved interrupt state, from printk_cpu_lock_irqsave().
+ */
+#define printk_cpu_unlock_irqrestore(flags) \
+ do { \
+ __printk_cpu_unlock(); \
+ local_irq_restore(flags); \
+ } while (0) \
+
+#else
+
+#define printk_cpu_lock_irqsave(flags) ((void)flags)
+#define printk_cpu_unlock_irqrestore(flags) ((void)flags)
+
+#endif /* CONFIG_SMP */
+
extern int kptr_restrict;
/**