diff options
Diffstat (limited to 'debian/patches-rt/0011-nbcon-Add-API-to-acquire-context-for-non-printing-op.patch')
-rw-r--r-- | debian/patches-rt/0011-nbcon-Add-API-to-acquire-context-for-non-printing-op.patch | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/debian/patches-rt/0011-nbcon-Add-API-to-acquire-context-for-non-printing-op.patch b/debian/patches-rt/0011-nbcon-Add-API-to-acquire-context-for-non-printing-op.patch new file mode 100644 index 0000000000..0245fc1ecd --- /dev/null +++ b/debian/patches-rt/0011-nbcon-Add-API-to-acquire-context-for-non-printing-op.patch @@ -0,0 +1,180 @@ +From: John Ogness <john.ogness@linutronix.de> +Date: Wed, 17 Apr 2024 12:42:46 +0000 +Subject: [PATCH 11/48] nbcon: Add API to acquire context for non-printing + operations +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.10/older/patches-6.10.2-rt14.tar.xz + +Provide functions nbcon_device_try_acquire() and +nbcon_device_release() which will try to acquire the nbcon +console ownership with NBCON_PRIO_NORMAL and mark it unsafe for +handover/takeover. + +These functions are to be used together with the device-specific +locking when performing non-printing activities on the console +device. They will allow synchronization against the +atomic_write() callback which will be serialized, for higher +priority contexts, only by acquiring the console context +ownership. + +Pitfalls: + +The API requires to be called in a context with migration +disabled because it uses per-CPU variables internally. + +The context is set unsafe for a takeover all the time. It +guarantees full serialization against any atomic_write() caller +except for the final flush in panic() which might try an unsafe +takeover. + +Signed-off-by: John Ogness <john.ogness@linutronix.de> +Reviewed-by: Petr Mladek <pmladek@suse.com> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + include/linux/console.h | 2 + + include/linux/printk.h | 15 ++++++++++++ + kernel/printk/nbcon.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++- + 3 files changed, 72 insertions(+), 1 deletion(-) + +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -322,6 +322,7 @@ struct nbcon_write_context { + * + * @nbcon_state: State for nbcon consoles + * @nbcon_seq: Sequence number of the next record for nbcon to print ++ * @nbcon_device_ctxt: Context available for non-printing operations + * @pbufs: Pointer to nbcon private buffer + */ + struct console { +@@ -417,6 +418,7 @@ struct console { + + atomic_t __private nbcon_state; + atomic_long_t __private nbcon_seq; ++ struct nbcon_context __private nbcon_device_ctxt; + struct printk_buffers *pbufs; + }; + +--- a/include/linux/printk.h ++++ b/include/linux/printk.h +@@ -9,6 +9,8 @@ + #include <linux/ratelimit_types.h> + #include <linux/once_lite.h> + ++struct console; ++ + extern const char linux_banner[]; + extern const char linux_proc_banner[]; + +@@ -194,6 +196,8 @@ extern asmlinkage void dump_stack_lvl(co + extern asmlinkage void dump_stack(void) __cold; + void printk_trigger_flush(void); + void console_replay_all(void); ++extern bool nbcon_device_try_acquire(struct console *con); ++extern void nbcon_device_release(struct console *con); + #else + static inline __printf(1, 0) + int vprintk(const char *s, va_list args) +@@ -273,9 +277,20 @@ static inline void dump_stack(void) + static inline void printk_trigger_flush(void) + { + } ++ + static inline void console_replay_all(void) + { + } ++ ++static inline bool nbcon_device_try_acquire(struct console *con) ++{ ++ return false; ++} ++ ++static inline void nbcon_device_release(struct console *con) ++{ ++} ++ + #endif + + bool this_cpu_in_panic(void); +--- a/kernel/printk/nbcon.c ++++ b/kernel/printk/nbcon.c +@@ -5,7 +5,9 @@ + #include <linux/kernel.h> + #include <linux/console.h> + #include <linux/delay.h> ++#include <linux/export.h> + #include <linux/slab.h> ++#include <linux/string.h> + #include "internal.h" + /* + * Printk console printing implementation for consoles which does not depend +@@ -528,6 +530,7 @@ static struct printk_buffers panic_nbcon + * nbcon_context_try_acquire - Try to acquire nbcon console + * @ctxt: The context of the caller + * ++ * Context: Under @ctxt->con->device_lock() or local_irq_save(). + * Return: True if the console was acquired. False otherwise. + * + * If the caller allowed an unsafe hostile takeover, on success the +@@ -535,7 +538,6 @@ static struct printk_buffers panic_nbcon + * in an unsafe state. Otherwise, on success the caller may assume + * the console is not in an unsafe state. + */ +-__maybe_unused + static bool nbcon_context_try_acquire(struct nbcon_context *ctxt) + { + unsigned int cpu = smp_processor_id(); +@@ -989,3 +991,55 @@ void nbcon_free(struct console *con) + + con->pbufs = NULL; + } ++ ++/** ++ * nbcon_device_try_acquire - Try to acquire nbcon console and enter unsafe ++ * section ++ * @con: The nbcon console to acquire ++ * ++ * Context: Under the locking mechanism implemented in ++ * @con->device_lock() including disabling migration. ++ * Return: True if the console was acquired. False otherwise. ++ * ++ * Console drivers will usually use their own internal synchronization ++ * mechasism to synchronize between console printing and non-printing ++ * activities (such as setting baud rates). However, nbcon console drivers ++ * supporting atomic consoles may also want to mark unsafe sections when ++ * performing non-printing activities in order to synchronize against their ++ * atomic_write() callback. ++ * ++ * This function acquires the nbcon console using priority NBCON_PRIO_NORMAL ++ * and marks it unsafe for handover/takeover. ++ */ ++bool nbcon_device_try_acquire(struct console *con) ++{ ++ struct nbcon_context *ctxt = &ACCESS_PRIVATE(con, nbcon_device_ctxt); ++ ++ cant_migrate(); ++ ++ memset(ctxt, 0, sizeof(*ctxt)); ++ ctxt->console = con; ++ ctxt->prio = NBCON_PRIO_NORMAL; ++ ++ if (!nbcon_context_try_acquire(ctxt)) ++ return false; ++ ++ if (!nbcon_context_enter_unsafe(ctxt)) ++ return false; ++ ++ return true; ++} ++EXPORT_SYMBOL_GPL(nbcon_device_try_acquire); ++ ++/** ++ * nbcon_device_release - Exit unsafe section and release the nbcon console ++ * @con: The nbcon console acquired in nbcon_device_try_acquire() ++ */ ++void nbcon_device_release(struct console *con) ++{ ++ struct nbcon_context *ctxt = &ACCESS_PRIVATE(con, nbcon_device_ctxt); ++ ++ if (nbcon_context_exit_unsafe(ctxt)) ++ nbcon_context_release(ctxt); ++} ++EXPORT_SYMBOL_GPL(nbcon_device_release); |