Re: [PATCH 2/2] kdb: Call vkdb_printf() from vprintk_default() only when wanted

From: Daniel Thompson
Date: Mon Nov 07 2016 - 05:27:25 EST


On 21/10/16 13:50, Petr Mladek wrote:
kdb_trap_printk allows to pass normal printk() messages to kdb via
vkdb_printk(). For example, it is used to get backtrace using
the classic show_stack(), see kdb_show_stack().

vkdb_printf() tries to avoid a potential infinite loop by disabling
the trap. But this approach is racy, for example:

CPU1 CPU2

vkdb_printf()
// assume that kdb_trap_printk == 0
saved_trap_printk = kdb_trap_printk;
kdb_trap_printk = 0;

kdb_show_stack()
kdb_trap_printk++;

When kdb is running any of the commands that use kdb_trap_printk there is a single active CPU and the other CPUs should be in a holding pen inside kgdb_cpu_enter().

The only time this is violated is when there is a timeout waiting for the other CPUs to report to the holding pen.


diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index d5e397315473..db73e33811e7 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -1941,7 +1941,9 @@ int vprintk_default(const char *fmt, va_list args)
int r;

#ifdef CONFIG_KGDB_KDB
- if (unlikely(kdb_trap_printk)) {
+ /* Allow to pass printk() to kdb but avoid a recursion. */
+ if (unlikely(kdb_trap_printk &&
+ kdb_printf_cpu != smp_processor_id())) {

Firstly, why !=?

Secondly, if kdb_trap_printk is set and the "wrong" CPU calls printk then we have an opportunity to trap a rouge processor in the holding pen meaning the test should probably be part of vkdb_printk() anyway.


Daniel.