From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S944726AbcJSPSz (ORCPT ); Wed, 19 Oct 2016 11:18:55 -0400 Received: from bombadil.infradead.org ([198.137.202.9]:54772 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S944710AbcJSPSv (ORCPT ); Wed, 19 Oct 2016 11:18:51 -0400 Date: Wed, 19 Oct 2016 17:18:41 +0200 From: Peter Zijlstra To: Petr Mladek Cc: Sergey Senozhatsky , Andrew Morton , Jan Kara , Tejun Heo , Calvin Owens , Thomas Gleixner , Mel Gorman , Steven Rostedt , Ingo Molnar , linux-kernel@vger.kernel.org, Jason Wessel Subject: Re: [PATCH 1/3] printk: Fix kdb_trap_printk placement Message-ID: <20161019151841.GP3102@twins.programming.kicks-ass.net> References: <20161018170830.405990950@infradead.org> <20161018171513.585962054@infradead.org> <20161019144140.GG11071@pathway.suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20161019144140.GG11071@pathway.suse.cz> User-Agent: Mutt/1.5.23.1 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Oct 19, 2016 at 04:41:40PM +0200, Petr Mladek wrote: > On Tue 2016-10-18 19:08:31, Peter Zijlstra wrote: > > Some people figured vprintk_emit() makes for a nice API and exported > > it, bypassing the kdb trap. > > > > This still leaves vprintk_nmi() outside of the kbd reach, should that > > be fixed too? > > Good question! vkdb_printf() tries to avoid a deadlock but the code is racy: > > int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap) > { > [...] > /* Serialize kdb_printf if multiple cpus try to write at once. > * But if any cpu goes recursive in kdb, just print the output, > * even if it is interleaved with any other text. > */ > if (!KDB_STATE(PRINTF_LOCK)) { > KDB_STATE_SET(PRINTF_LOCK); > spin_lock_irqsave(&kdb_printf_lock, flags); > got_printf_lock = 1; > atomic_inc(&kdb_event); > } else { > __acquire(kdb_printf_lock); > } > > > Let's have the following situation: > > CPU1 CPU2 > > if (!KDB_STATE(PRINTF_LOCK)) { > KDB_STATE_SET(PRINTF_LOCK); > > if (!KDB_STATE(PRINTF_LOCK)) { > } else { > __acquire(kdb_printf_lock); > } > > Now, both CPUs are in the critical section and happily writing over each > other, e.g. in > > vsnprintf(next_avail, size_avail, fmt, ap); > > I quess that we want to fix this race. But I am not sure if it will > be done an NMI-safe way. I am going to send a patch for this. Something like patch 3 in this series should do I suppose. But the vkdb_printf() thing using spin_lock_irqsave() seems to suggest it was never meant to be used from NMI context.