[PATCH] printk: nbcon: Prevent deadlock when flushing nbcon consoles in the legacy loop

From: Petr Mladek
Date: Thu Apr 11 2024 - 09:45:53 EST


Ignore pending records in nbcon consoles in the legacy console_flush_all()
loop when the nbcon console context can't be acquired. They will be
flushed either by the current nbcon context owner or to-be-introduced
printk kthread.

Signed-off-by: Petr Mladek <pmladek@xxxxxxxx>
---
kernel/printk/nbcon.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c
index c57ad34a8d56..88c40f165be4 100644
--- a/kernel/printk/nbcon.c
+++ b/kernel/printk/nbcon.c
@@ -964,8 +964,12 @@ static __ref unsigned int *nbcon_get_cpu_emergency_nesting(void)
* write_atomic() callback
* @wctxt: An initialized write context struct to use for this context
*
- * Return: False if it is known there are no more records to print,
- * otherwise true.
+ * Return: True, when a record has been printed and there are still
+ * pending records. The caller might want to continue flushing.
+ *
+ * False, when there is no pending record, or when the console
+ * context can't be acquired, or the ownership has been lost.
+ * The caller should give up. Either the job is or can't be done.
*
* This is an internal helper to handle the locking of the console before
* calling nbcon_emit_next_record().
@@ -975,7 +979,7 @@ static bool nbcon_atomic_emit_one(struct nbcon_write_context *wctxt)
struct nbcon_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt);

if (!nbcon_context_try_acquire(ctxt))
- return true;
+ return false;

/*
* nbcon_emit_next_record() returns false when the console was
@@ -983,7 +987,7 @@ static bool nbcon_atomic_emit_one(struct nbcon_write_context *wctxt)
* longer valid.
*/
if (!nbcon_emit_next_record(wctxt))
- return true;
+ return false;

nbcon_context_release(ctxt);

@@ -1023,8 +1027,13 @@ enum nbcon_prio nbcon_get_default_prio(void)
* @cookie: The cookie from the SRCU read lock.
*
* Context: Any context except NMI.
- * Return: False if the given console has no next record to print,
- * otherwise true.
+ *
+ * Return: True, when a record has been printed and there are still
+ * pending records. The caller might want to continue flushing.
+ *
+ * False, when there is no pending record, or when the console
+ * context can't be acquired, or the ownership has been lost.
+ * The caller should give up. Either the job is or can't be done.
*
* This function is meant to be called by console_flush_all() to print records
* on nbcon consoles from legacy context (printing via console unlocking).
--
2.44.0


Best Regards,
Petr