From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754721AbcKJI7V (ORCPT ); Thu, 10 Nov 2016 03:59:21 -0500 Received: from Galois.linutronix.de ([146.0.238.70]:60758 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753880AbcKJI7T (ORCPT ); Thu, 10 Nov 2016 03:59:19 -0500 Date: Thu, 10 Nov 2016 09:56:41 +0100 (CET) From: Thomas Gleixner To: Lu Baolu cc: Greg Kroah-Hartman , Mathias Nyman , Ingo Molnar , linux-usb@vger.kernel.org, x86@kernel.org, LKML , Peter Zijlstra Subject: Re: [PATCH v4 1/4] usb: dbc: early driver for xhci debug capability In-Reply-To: <5823CB63.7090603@linux.intel.com> Message-ID: References: <1477976354-13291-1-git-send-email-baolu.lu@linux.intel.com> <1477976354-13291-2-git-send-email-baolu.lu@linux.intel.com> <5823CB63.7090603@linux.intel.com> User-Agent: Alpine 2.20 (DEB 67 2015-01-07) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, 10 Nov 2016, Lu Baolu wrote: > On 11/09/2016 05:37 PM, Thomas Gleixner wrote: > > On Tue, 1 Nov 2016, Lu Baolu wrote: > >> +static void early_xdbc_write(struct console *con, const char *str, u32 n) > >> +{ > >> + int chunk, ret; > >> + static char buf[XDBC_MAX_PACKET]; > >> + int use_cr = 0; > >> + > >> + if (!xdbc.xdbc_reg) > >> + return; > >> + memset(buf, 0, XDBC_MAX_PACKET); > > How is that dealing with reentrancy? > > > > early_printk() does not protect against it. Peter has a patch to prevent > > concurrent access from different cpus, but it cannot and will never prevent > > reentrancy on the same cpu (interrupt, nmi). > > I can use a spinlock_irq to protect reentrancy of interrupt on the same > cpu. But I have no idea about the nmi one. spinlock wont work due to NMIs. > This seems to be a common issue for all early printk drivers. No. The other early printk drivers like serial do not have that problem as they simply do: while (*buf) { while (inb(UART) & TX_BUSY) cpu_relax(); outb(*buf++, UART); } The wait for the UART to become ready is independent of the context as it solely depends on the hardware. As a result you can see the output from irq/nmi intermingled with the one from thread context, but that's the only problem they have. The only thing you can do to make this work is to prevent printing in NMI context: write() { if (in_nmi()) return; raw_spinlock_irqsave(&lock, flags); .... That fully serializes the writes and just ignores NMI context printks. Not optimal, but I fear that's all you can do. Thanks, tglx