Skip to content

Commit 696ffaf

Browse files
jognesspmladek
authored andcommitted
printk: Consolidate console deferred printing
Printing to consoles can be deferred for several reasons: - explicitly with printk_deferred() - printk() in NMI context - recursive printk() calls The current implementation is not consistent. For printk_deferred(), irq work is scheduled twice. For NMI und recursive, panic CPU suppression and caller delays are not properly enforced. Correct these inconsistencies by consolidating the deferred printing code so that vprintk_deferred() is the top-level function for deferred printing and vprintk_emit() will perform whichever irq_work queueing is appropriate. Also add kerneldoc for wake_up_klogd() and defer_console_output() to clarify their differences and appropriate usage. Signed-off-by: John Ogness <john.ogness@linutronix.de> Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org> Reviewed-by: Petr Mladek <pmladek@suse.com> Signed-off-by: Petr Mladek <pmladek@suse.com> Link: https://lore.kernel.org/r/20230717194607.145135-6-john.ogness@linutronix.de
1 parent eacb04f commit 696ffaf

File tree

2 files changed

+30
-14
lines changed

2 files changed

+30
-14
lines changed

kernel/printk/printk.c

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2306,7 +2306,11 @@ asmlinkage int vprintk_emit(int facility, int level,
23062306
preempt_enable();
23072307
}
23082308

2309-
wake_up_klogd();
2309+
if (in_sched)
2310+
defer_console_output();
2311+
else
2312+
wake_up_klogd();
2313+
23102314
return printed_len;
23112315
}
23122316
EXPORT_SYMBOL(vprintk_emit);
@@ -3841,11 +3845,33 @@ static void __wake_up_klogd(int val)
38413845
preempt_enable();
38423846
}
38433847

3848+
/**
3849+
* wake_up_klogd - Wake kernel logging daemon
3850+
*
3851+
* Use this function when new records have been added to the ringbuffer
3852+
* and the console printing of those records has already occurred or is
3853+
* known to be handled by some other context. This function will only
3854+
* wake the logging daemon.
3855+
*
3856+
* Context: Any context.
3857+
*/
38443858
void wake_up_klogd(void)
38453859
{
38463860
__wake_up_klogd(PRINTK_PENDING_WAKEUP);
38473861
}
38483862

3863+
/**
3864+
* defer_console_output - Wake kernel logging daemon and trigger
3865+
* console printing in a deferred context
3866+
*
3867+
* Use this function when new records have been added to the ringbuffer,
3868+
* this context is responsible for console printing those records, but
3869+
* the current context is not allowed to perform the console printing.
3870+
* Trigger an irq_work context to perform the console printing. This
3871+
* function also wakes the logging daemon.
3872+
*
3873+
* Context: Any context.
3874+
*/
38493875
void defer_console_output(void)
38503876
{
38513877
/*
@@ -3862,12 +3888,7 @@ void printk_trigger_flush(void)
38623888

38633889
int vprintk_deferred(const char *fmt, va_list args)
38643890
{
3865-
int r;
3866-
3867-
r = vprintk_emit(0, LOGLEVEL_SCHED, NULL, fmt, args);
3868-
defer_console_output();
3869-
3870-
return r;
3891+
return vprintk_emit(0, LOGLEVEL_SCHED, NULL, fmt, args);
38713892
}
38723893

38733894
int _printk_deferred(const char *fmt, ...)

kernel/printk/printk_safe.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,8 @@ asmlinkage int vprintk(const char *fmt, va_list args)
3838
* Use the main logbuf even in NMI. But avoid calling console
3939
* drivers that might have their own locks.
4040
*/
41-
if (this_cpu_read(printk_context) || in_nmi()) {
42-
int len;
43-
44-
len = vprintk_store(0, LOGLEVEL_DEFAULT, NULL, fmt, args);
45-
defer_console_output();
46-
return len;
47-
}
41+
if (this_cpu_read(printk_context) || in_nmi())
42+
return vprintk_deferred(fmt, args);
4843

4944
/* No obstacles. */
5045
return vprintk_default(fmt, args);

0 commit comments

Comments
 (0)