Skip to content

Commit 3db488c

Browse files
committed
Merge branch 'rework/fixes' into for-linus
2 parents 8ac4bf0 + 571c1ea commit 3db488c

File tree

1 file changed

+41
-22
lines changed

1 file changed

+41
-22
lines changed

kernel/printk/nbcon.c

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,9 @@ static void nbcon_seq_try_update(struct nbcon_context *ctxt, u64 new_seq)
214214

215215
/**
216216
* nbcon_context_try_acquire_direct - Try to acquire directly
217-
* @ctxt: The context of the caller
218-
* @cur: The current console state
217+
* @ctxt: The context of the caller
218+
* @cur: The current console state
219+
* @is_reacquire: This acquire is a reacquire
219220
*
220221
* Acquire the console when it is released. Also acquire the console when
221222
* the current owner has a lower priority and the console is in a safe state.
@@ -225,32 +226,38 @@ static void nbcon_seq_try_update(struct nbcon_context *ctxt, u64 new_seq)
225226
*
226227
* Errors:
227228
*
228-
* -EPERM: A panic is in progress and this is not the panic CPU.
229-
* Or the current owner or waiter has the same or higher
230-
* priority. No acquire method can be successful in
231-
* this case.
229+
* -EPERM: A panic is in progress and this is neither the panic
230+
* CPU nor is this a reacquire. Or the current owner or
231+
* waiter has the same or higher priority. No acquire
232+
* method can be successful in these cases.
232233
*
233234
* -EBUSY: The current owner has a lower priority but the console
234235
* in an unsafe state. The caller should try using
235236
* the handover acquire method.
236237
*/
237238
static int nbcon_context_try_acquire_direct(struct nbcon_context *ctxt,
238-
struct nbcon_state *cur)
239+
struct nbcon_state *cur, bool is_reacquire)
239240
{
240241
unsigned int cpu = smp_processor_id();
241242
struct console *con = ctxt->console;
242243
struct nbcon_state new;
243244

244245
do {
245246
/*
246-
* Panic does not imply that the console is owned. However, it
247-
* is critical that non-panic CPUs during panic are unable to
248-
* acquire ownership in order to satisfy the assumptions of
249-
* nbcon_waiter_matches(). In particular, the assumption that
250-
* lower priorities are ignored during panic.
247+
* Panic does not imply that the console is owned. However,
248+
* since all non-panic CPUs are stopped during panic(), it
249+
* is safer to have them avoid gaining console ownership.
250+
*
251+
* If this acquire is a reacquire (and an unsafe takeover
252+
* has not previously occurred) then it is allowed to attempt
253+
* a direct acquire in panic. This gives console drivers an
254+
* opportunity to perform any necessary cleanup if they were
255+
* interrupted by the panic CPU while printing.
251256
*/
252-
if (other_cpu_in_panic())
257+
if (other_cpu_in_panic() &&
258+
(!is_reacquire || cur->unsafe_takeover)) {
253259
return -EPERM;
260+
}
254261

255262
if (ctxt->prio <= cur->prio || ctxt->prio <= cur->req_prio)
256263
return -EPERM;
@@ -301,8 +308,9 @@ static bool nbcon_waiter_matches(struct nbcon_state *cur, int expected_prio)
301308
* Event #1 implies this context is EMERGENCY.
302309
* Event #2 implies the new context is PANIC.
303310
* Event #3 occurs when panic() has flushed the console.
304-
* Events #4 and #5 are not possible due to the other_cpu_in_panic()
305-
* check in nbcon_context_try_acquire_direct().
311+
* Event #4 occurs when a non-panic CPU reacquires.
312+
* Event #5 is not possible due to the other_cpu_in_panic() check
313+
* in nbcon_context_try_acquire_handover().
306314
*/
307315

308316
return (cur->req_prio == expected_prio);
@@ -431,6 +439,16 @@ static int nbcon_context_try_acquire_handover(struct nbcon_context *ctxt,
431439
WARN_ON_ONCE(ctxt->prio <= cur->prio || ctxt->prio <= cur->req_prio);
432440
WARN_ON_ONCE(!cur->unsafe);
433441

442+
/*
443+
* Panic does not imply that the console is owned. However, it
444+
* is critical that non-panic CPUs during panic are unable to
445+
* wait for a handover in order to satisfy the assumptions of
446+
* nbcon_waiter_matches(). In particular, the assumption that
447+
* lower priorities are ignored during panic.
448+
*/
449+
if (other_cpu_in_panic())
450+
return -EPERM;
451+
434452
/* Handover is not possible on the same CPU. */
435453
if (cur->cpu == cpu)
436454
return -EBUSY;
@@ -558,7 +576,8 @@ static struct printk_buffers panic_nbcon_pbufs;
558576

559577
/**
560578
* nbcon_context_try_acquire - Try to acquire nbcon console
561-
* @ctxt: The context of the caller
579+
* @ctxt: The context of the caller
580+
* @is_reacquire: This acquire is a reacquire
562581
*
563582
* Context: Under @ctxt->con->device_lock() or local_irq_save().
564583
* Return: True if the console was acquired. False otherwise.
@@ -568,7 +587,7 @@ static struct printk_buffers panic_nbcon_pbufs;
568587
* in an unsafe state. Otherwise, on success the caller may assume
569588
* the console is not in an unsafe state.
570589
*/
571-
static bool nbcon_context_try_acquire(struct nbcon_context *ctxt)
590+
static bool nbcon_context_try_acquire(struct nbcon_context *ctxt, bool is_reacquire)
572591
{
573592
unsigned int cpu = smp_processor_id();
574593
struct console *con = ctxt->console;
@@ -577,7 +596,7 @@ static bool nbcon_context_try_acquire(struct nbcon_context *ctxt)
577596

578597
nbcon_state_read(con, &cur);
579598
try_again:
580-
err = nbcon_context_try_acquire_direct(ctxt, &cur);
599+
err = nbcon_context_try_acquire_direct(ctxt, &cur, is_reacquire);
581600
if (err != -EBUSY)
582601
goto out;
583602

@@ -913,7 +932,7 @@ void nbcon_reacquire_nobuf(struct nbcon_write_context *wctxt)
913932
{
914933
struct nbcon_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt);
915934

916-
while (!nbcon_context_try_acquire(ctxt))
935+
while (!nbcon_context_try_acquire(ctxt, true))
917936
cpu_relax();
918937

919938
nbcon_write_context_set_buf(wctxt, NULL, 0);
@@ -1101,7 +1120,7 @@ static bool nbcon_emit_one(struct nbcon_write_context *wctxt, bool use_atomic)
11011120
cant_migrate();
11021121
}
11031122

1104-
if (!nbcon_context_try_acquire(ctxt))
1123+
if (!nbcon_context_try_acquire(ctxt, false))
11051124
goto out;
11061125

11071126
/*
@@ -1486,7 +1505,7 @@ static int __nbcon_atomic_flush_pending_con(struct console *con, u64 stop_seq,
14861505
ctxt->prio = nbcon_get_default_prio();
14871506
ctxt->allow_unsafe_takeover = allow_unsafe_takeover;
14881507

1489-
if (!nbcon_context_try_acquire(ctxt))
1508+
if (!nbcon_context_try_acquire(ctxt, false))
14901509
return -EPERM;
14911510

14921511
while (nbcon_seq_read(con) < stop_seq) {
@@ -1784,7 +1803,7 @@ bool nbcon_device_try_acquire(struct console *con)
17841803
ctxt->console = con;
17851804
ctxt->prio = NBCON_PRIO_NORMAL;
17861805

1787-
if (!nbcon_context_try_acquire(ctxt))
1806+
if (!nbcon_context_try_acquire(ctxt, false))
17881807
return false;
17891808

17901809
if (!nbcon_context_enter_unsafe(ctxt))

0 commit comments

Comments
 (0)