printk: nbcon: Provide function to reacquire ownership
BugLink: https://bugs.launchpad.net/bugs/2060704 Contexts may become nbcon owners for various reasons, not just for printing. Indeed, the port->lock wrapper takes ownership for anything relating to the hardware. Since ownership can be lost at any time due to handover or takeover, a context _should_ be prepared to back out immediately and carefully. However, there are many scenarios where the context _must_ reacquire ownership in order to finalize or revert hardware changes. One such example is when interrupts are disabled by a context. No other context will automagically re-enable the interrupts. For this case, the disabling context _must_ reacquire nbcon ownership so that it can re-enable the interrupts. Provide nbcon_reacquire() for exactly this purpose. Note that for printing contexts, after a successful reacquire the context will have no output buffer because that has been lost. nbcon_reacquire() cannot be used to resume printing. Signed-off-by: John Ogness <john.ogness@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Kevin Becker <kevin.becker@canonical.com>
This commit is contained in:
committed by
Kevin Becker
parent
7cdfa7fb25
commit
9f0985dcf8
@@ -371,6 +371,11 @@ struct console {
|
||||
* functions are also points of possible ownership transfer. If
|
||||
* either function returns false, ownership has been lost.
|
||||
*
|
||||
* If the driver must reacquire ownership in order to finalize or
|
||||
* revert hardware changes, nbcon_reacquire() can be used. However,
|
||||
* on reacquire the buffer content is no longer available. A
|
||||
* reacquire cannot be used to resume printing.
|
||||
*
|
||||
* This callback can be called from any context (including NMI).
|
||||
* Therefore it must avoid usage of any locking and instead rely
|
||||
* on the console ownership for synchronization.
|
||||
@@ -595,12 +600,14 @@ extern void nbcon_cpu_emergency_exit(void);
|
||||
extern bool nbcon_can_proceed(struct nbcon_write_context *wctxt);
|
||||
extern bool nbcon_enter_unsafe(struct nbcon_write_context *wctxt);
|
||||
extern bool nbcon_exit_unsafe(struct nbcon_write_context *wctxt);
|
||||
extern void nbcon_reacquire(struct nbcon_write_context *wctxt);
|
||||
#else
|
||||
static inline void nbcon_cpu_emergency_enter(void) { }
|
||||
static inline void nbcon_cpu_emergency_exit(void) { }
|
||||
static inline bool nbcon_can_proceed(struct nbcon_write_context *wctxt) { return false; }
|
||||
static inline bool nbcon_enter_unsafe(struct nbcon_write_context *wctxt) { return false; }
|
||||
static inline bool nbcon_exit_unsafe(struct nbcon_write_context *wctxt) { return false; }
|
||||
static inline void nbcon_reacquire(struct nbcon_write_context *wctxt) { }
|
||||
#endif
|
||||
|
||||
extern int console_set_on_cmdline;
|
||||
|
||||
@@ -838,6 +838,38 @@ bool nbcon_exit_unsafe(struct nbcon_write_context *wctxt)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nbcon_exit_unsafe);
|
||||
|
||||
/**
|
||||
* nbcon_reacquire - Reacquire a console after losing ownership
|
||||
* @wctxt: The write context that was handed to the write function
|
||||
*
|
||||
* Since ownership can be lost at any time due to handover or takeover, a
|
||||
* printing context _should_ be prepared to back out immediately and
|
||||
* carefully. However, there are many scenarios where the context _must_
|
||||
* reacquire ownership in order to finalize or revert hardware changes.
|
||||
*
|
||||
* This function allows a context to reacquire ownership using the same
|
||||
* priority as its previous ownership.
|
||||
*
|
||||
* Note that for printing contexts, after a successful reacquire the
|
||||
* context will have no output buffer because that has been lost. This
|
||||
* function cannot be used to resume printing.
|
||||
*/
|
||||
void nbcon_reacquire(struct nbcon_write_context *wctxt)
|
||||
{
|
||||
struct nbcon_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt);
|
||||
struct console *con = ctxt->console;
|
||||
struct nbcon_state cur;
|
||||
|
||||
while (!nbcon_context_try_acquire(ctxt))
|
||||
cpu_relax();
|
||||
|
||||
wctxt->outbuf = NULL;
|
||||
wctxt->len = 0;
|
||||
nbcon_state_read(con, &cur);
|
||||
wctxt->unsafe_takeover = cur.unsafe_takeover;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nbcon_reacquire);
|
||||
|
||||
/**
|
||||
* nbcon_emit_next_record - Emit a record in the acquired context
|
||||
* @wctxt: The write context that will be handed to the write function
|
||||
@@ -945,6 +977,15 @@ static bool nbcon_emit_next_record(struct nbcon_write_context *wctxt, bool use_a
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!wctxt->outbuf) {
|
||||
/*
|
||||
* Ownership was lost and reacquired by the driver.
|
||||
* Handle it as if ownership was lost and try to continue.
|
||||
*/
|
||||
nbcon_context_release(ctxt);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since any dropped message was successfully output, reset the
|
||||
* dropped count for the console.
|
||||
|
||||
Reference in New Issue
Block a user