Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752538AbcKGKZn (ORCPT ); Mon, 7 Nov 2016 05:25:43 -0500 Received: from mail-wm0-f51.google.com ([74.125.82.51]:36109 "EHLO mail-wm0-f51.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751534AbcKGKYY (ORCPT ); Mon, 7 Nov 2016 05:24:24 -0500 Subject: Re: [PATCH 2/2] kdb: Call vkdb_printf() from vprintk_default() only when wanted To: Petr Mladek , Jason Wessel References: <1477054235-1624-1-git-send-email-pmladek@suse.com> <1477054235-1624-3-git-send-email-pmladek@suse.com> Cc: Peter Zijlstra , Andrew Morton , Sergey Senozhatsky , linux-kernel@vger.kernel.org From: Daniel Thompson Message-ID: <73b8fe23-4fc7-9d56-ed78-a3d6b398ad74@linaro.org> Date: Mon, 7 Nov 2016 10:24:22 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 MIME-Version: 1.0 In-Reply-To: <1477054235-1624-3-git-send-email-pmladek@suse.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1535 Lines: 47 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.