mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
nbcon: Add API to acquire context for non-printing operations
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> Link: https://lore.kernel.org/r/20240820063001.36405-14-john.ogness@linutronix.de Signed-off-by: Petr Mladek <pmladek@suse.com>
This commit is contained in:
parent
dc219d8d85
commit
adf6f37d14
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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[];
|
||||
|
||||
@ -198,6 +200,8 @@ extern asmlinkage void dump_stack_lvl(const char *log_lvl) __cold;
|
||||
extern asmlinkage void dump_stack(void) __cold;
|
||||
void printk_trigger_flush(void);
|
||||
void console_try_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)
|
||||
@ -280,6 +284,16 @@ static inline void printk_trigger_flush(void)
|
||||
static inline void console_try_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);
|
||||
|
@ -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
|
||||
@ -546,6 +548,7 @@ static struct printk_buffers panic_nbcon_pbufs;
|
||||
* 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
|
||||
@ -553,7 +556,6 @@ static struct printk_buffers panic_nbcon_pbufs;
|
||||
* 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();
|
||||
@ -1011,3 +1013,57 @@ 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))
|
||||
return;
|
||||
|
||||
nbcon_context_release(ctxt);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nbcon_device_release);
|
||||
|
Loading…
Reference in New Issue
Block a user