]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
printk/panic: Add option to allow non-panic CPUs to write to the ring buffer.
authorDonghyeok Choe <d7271.choe@samsung.com>
Tue, 18 Mar 2025 02:23:20 +0000 (11:23 +0900)
committerPetr Mladek <pmladek@suse.com>
Thu, 20 Mar 2025 14:48:36 +0000 (15:48 +0100)
Commit 779dbc2e78d7 ("printk: Avoid non-panic CPUs writing to ringbuffer")
aimed to isolate panic-related messages. However, when panic() itself
malfunctions, messages from non-panic CPUs become crucial for debugging.

While commit bcc954c6caba ("printk/panic: Allow cpu backtraces to
be written into ringbuffer during panic") enables non-panic CPU
backtraces, it may not provide sufficient diagnostic information.

Introduce the "debug_non_panic_cpus" command-line option, enabling
non-panic CPU messages to be stored in the ring buffer during a panic.
This also prevents discarding non-finalized messages from non-panic CPUs
during console flushing, providing a more comprehensive view of system
state during critical failures.

Link: https://lore.kernel.org/all/Z8cLEkqLL2IOyNIj@pathway/
Signed-off-by: Donghyeok Choe <d7271.choe@samsung.com>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/20250318022320.2428155-1-d7271.choe@samsung.com
[pmladek@suse.com: Added documentation, added module_parameter, removed printk_ prefix.]
Tested-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Petr Mladek <pmladek@suse.com>
Documentation/admin-guide/kernel-parameters.txt
kernel/printk/internal.h
kernel/printk/printk.c
kernel/printk/printk_ringbuffer.c

index 05f5935eeac8c0f83f11c80a85010dfe763915e5..961bc82f05998ec284a98ef868426a14a93b50dc 100644 (file)
                        Format: <bool>
                        default: 0 (auto_verbose is enabled)
 
+       printk.debug_non_panic_cpus=
+                       Allows storing messages from non-panic CPUs into
+                       the printk log buffer during panic(). They are
+                       flushed to consoles by the panic-CPU on
+                       a best-effort basis.
+                       Format: <bool> (1/Y/y=enable, 0/N/n=disable)
+                       Default: disabled
+
        printk.devkmsg={on,off,ratelimit}
                        Control writing to /dev/kmsg.
                        on - unlimited logging to /dev/kmsg from userspace
index a91bdf802967169db21d8c8ef176ee63bbd77705..48a24e7b309db20fdd7419f7aeda68ea7c79fd80 100644 (file)
@@ -64,6 +64,7 @@ struct dev_printk_info;
 
 extern struct printk_ringbuffer *prb;
 extern bool printk_kthreads_running;
+extern bool debug_non_panic_cpus;
 
 __printf(4, 0)
 int vprintk_store(int facility, int level,
index 2590498d8353a08e7887bf706b3c519409edeecf..74b4734a87b915b415b01efd0a47bc26bb72a0d8 100644 (file)
@@ -2375,6 +2375,22 @@ void printk_legacy_allow_panic_sync(void)
        }
 }
 
+bool __read_mostly debug_non_panic_cpus;
+
+#ifdef CONFIG_PRINTK_CALLER
+static int __init debug_non_panic_cpus_setup(char *str)
+{
+       debug_non_panic_cpus = true;
+       pr_info("allow messages from non-panic CPUs in panic()\n");
+
+       return 0;
+}
+early_param("debug_non_panic_cpus", debug_non_panic_cpus_setup);
+module_param(debug_non_panic_cpus, bool, 0644);
+MODULE_PARM_DESC(debug_non_panic_cpus,
+                "allow messages from non-panic CPUs in panic()");
+#endif
+
 asmlinkage int vprintk_emit(int facility, int level,
                            const struct dev_printk_info *dev_info,
                            const char *fmt, va_list args)
@@ -2391,7 +2407,9 @@ asmlinkage int vprintk_emit(int facility, int level,
         * non-panic CPUs are generating any messages, they will be
         * silently dropped.
         */
-       if (other_cpu_in_panic() && !panic_triggering_all_cpu_backtrace)
+       if (other_cpu_in_panic() &&
+           !debug_non_panic_cpus &&
+           !panic_triggering_all_cpu_backtrace)
                return 0;
 
        printk_get_console_flush_type(&ft);
index 88e8f3a61922913a280c51737184a44d005916bc..d9fb053cff67dbdb8741ee3cac60f51ab986e499 100644 (file)
@@ -2133,9 +2133,9 @@ static bool _prb_read_valid(struct printk_ringbuffer *rb, u64 *seq,
                         * there may be other finalized records beyond that
                         * need to be printed for a panic situation. If this
                         * is the panic CPU, skip this
-                        * non-existent/non-finalized record unless it is
-                        * at or beyond the head, in which case it is not
-                        * possible to continue.
+                        * non-existent/non-finalized record unless non-panic
+                        * CPUs are still running and their debugging is
+                        * explicitly enabled.
                         *
                         * Note that new messages printed on panic CPU are
                         * finalized when we are here. The only exception
@@ -2143,10 +2143,13 @@ static bool _prb_read_valid(struct printk_ringbuffer *rb, u64 *seq,
                         * But it would have the sequence number returned
                         * by "prb_next_reserve_seq() - 1".
                         */
-                       if (this_cpu_in_panic() && ((*seq + 1) < prb_next_reserve_seq(rb)))
+                       if (this_cpu_in_panic() &&
+                           (!debug_non_panic_cpus || legacy_allow_panic_sync) &&
+                           ((*seq + 1) < prb_next_reserve_seq(rb))) {
                                (*seq)++;
-                       else
+                       } else {
                                return false;
+                       }
                }
        }