>From f3bb7d49b59b61a30f2fefc2b241d3f535b2afd2 Mon Sep 17 00:00:00 2001 From: John Ogness Date: Thu, 8 Jan 2026 09:31:51 +0000 Subject: [PATCH] printk: Debug new vs. old suspend/resume behavior This is just for debugging. It should restore the old console_lock behavior for suspend/resume and also adds some debugging information. Please compile with CONFIG_PRINTK_CALLER=y so that we can see which tasks are locking/unlocking the console during suspend/resume. --- kernel/printk/printk.c | 61 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 1d765ad242b8..fd69cab4368e 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -356,6 +356,22 @@ static void __up_console_sem(unsigned long ip) */ static int console_locked; +static int console_suspended; + +int vprintk_store(int facility, int level, + const struct dev_printk_info *dev_info, + const char *fmt, va_list args); + +/* Helper function to store-only. */ +static void printk_store(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vprintk_store(0, LOGLEVEL_DEFAULT, NULL, fmt, args); + va_end(args); +} + /* * Array of consoles built from command line options (console=) */ @@ -2841,6 +2857,15 @@ void console_lock(void) msleep(1000); down_console_sem(); + if (console_suspended) { + printk_store(KERN_INFO "printk: %s\n", __func__); + /* + * Keep console locked, but do not touch + * @console_locked or @console_may_schedule. + * (Although they will both be 1 here anyway.) + */ + return; + } console_locked = 1; console_may_schedule = 1; } @@ -2861,6 +2886,15 @@ int console_trylock(void) return 0; if (down_trylock_console_sem()) return 0; + if (console_suspended) { + printk_store(KERN_INFO "printk: %s\n", __func__); + /* + * The lock was acquired, but unlock directly and report + * failure. Here console_locked=1 and console_may_schedule=1. + */ + up_console_sem(); + return 0; + } console_locked = 1; console_may_schedule = 0; return 1; @@ -3354,6 +3388,16 @@ void console_unlock(void) { struct console_flush_type ft; + if (console_suspended) { + printk_store(KERN_INFO "printk: %s\n", __func__); + /* + * Simply unlock directly. + * Here console_locked=1 and console_may_schedule=1. + */ + up_console_sem(); + return; + } + printk_get_console_flush_type(&ft); if (ft.legacy_direct) __console_flush_and_unlock(); @@ -3559,6 +3603,7 @@ struct tty_driver *console_device(int *index) void console_suspend(struct console *console) { __pr_flush(console, 1000, true); + console_list_lock(); console_srcu_write_flags(console, console->flags & ~CON_ENABLED); console_list_unlock(); @@ -3570,6 +3615,12 @@ void console_suspend(struct console *console) * using the port. */ synchronize_srcu(&console_srcu); + + console_lock(); + console_suspended = 1; + printk_store(KERN_INFO "printk: %s\n", __func__); + /* Unlock directly (i.e. without clearing @console_locked). */ + up_console_sem(); } EXPORT_SYMBOL(console_suspend); @@ -3597,6 +3648,16 @@ void console_resume(struct console *console) defer_console_output(); __pr_flush(console, 1000, true); + + down_console_sem(); + printk_store(KERN_INFO "printk: %s\n", __func__); + console_suspended = 0; + /* + * Perform a regular unlock. + * Here console_locked=1 and console_may_schedule=1. + * @console_unlocked will be cleared. + */ + console_unlock(); } EXPORT_SYMBOL(console_resume); -- 2.30.2