From patchwork Mon Dec 19 01:14:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 9479519 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 723C8601C2 for ; Mon, 19 Dec 2016 01:15:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 60AF728414 for ; Mon, 19 Dec 2016 01:15:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 53A4D2845C; Mon, 19 Dec 2016 01:15:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D301B28414 for ; Mon, 19 Dec 2016 01:15:20 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1cImXr-0006dC-SP; Mon, 19 Dec 2016 01:15:15 +0000 Received: from mail-pf0-x229.google.com ([2607:f8b0:400e:c00::229]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1cImXq-0005uU-0J for linux-rockchip@lists.infradead.org; Mon, 19 Dec 2016 01:15:14 +0000 Received: by mail-pf0-x229.google.com with SMTP id c4so20821381pfb.1 for ; Sun, 18 Dec 2016 17:14:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id; bh=kgb3z4iBAfofZmT08fgS07GYsl8V8fdTNQYpl0KIuws=; b=QagFR1Vxogv6VP5ODRfHeL2SRAdio3xh885CtxRZuZL4vV9Agg01Qqt8mbLB6RmASD tjdoCfSxuuc7cR7dQ8IoKoWOD9R50Cd56WhVJ5poMdV0RnzWLy0FOx6+SNncM7SKH3qj BkLzDeDODTmyIL6ExDgUduYWaVQf6RXcfCJyo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=kgb3z4iBAfofZmT08fgS07GYsl8V8fdTNQYpl0KIuws=; b=EZQF4ZblpMpL1YRjPjxUwhBm685m+9+SJhFxB60w8412gJcst3Pr9rPcr+sK9s+iS1 E382dwRc5VjteYPS1RymFK1Qyoe8z1kt5GJutd6DzgTYG8xH/hfznPsAJ32w0xcvaGl7 JMOwKOCZ/H3nnQmAGT/pymhBjRYtyCMBNrNJtomtCR6FTAMmblG5HzDmMjPPE2STp5nP 0PhBP8rrfEbbmhWWb+rIS+lSwfrWZnWe7OP2bwRTo+57U4kRIApybq1WmAw0nLkvMQF5 9mqDfv/OorryYCBj70FBYI6M6Mvamk2kki+WQBycl/rd7J9mONfVtv0aLjWWdHG2Y4ow VBjA== X-Gm-Message-State: AKaTC03QMsEAEPWe4d5nsjQHZ8RI9VZwsjhlJTtl3Ujy8x/pyovU62NxWu7RjAw/dGw53jKt X-Received: by 10.84.202.12 with SMTP id w12mr30143701pld.156.1482110092757; Sun, 18 Dec 2016 17:14:52 -0800 (PST) Received: from tictac.mtv.corp.google.com ([172.22.65.76]) by smtp.gmail.com with ESMTPSA id q9sm26501182pfg.47.2016.12.18.17.14.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 18 Dec 2016 17:14:51 -0800 (PST) From: Douglas Anderson To: gregkh@linuxfoundation.org, jslaby@suse.com Subject: [PATCH] serial: 8250: Avoid "too much work" from bogus rx timeout interrupt Date: Sun, 18 Dec 2016 17:14:27 -0800 Message-Id: <1482110067-5591-1-git-send-email-dianders@chromium.org> X-Mailer: git-send-email 2.8.0.rc3.226.g39d4020 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20161218_171514_149054_F62B5D87 X-CRM114-Status: GOOD ( 13.37 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: briannorris@chromium.org, yegorslists@googlemail.com, peter@hurleysoftware.com, linux-kernel@vger.kernel.org, jeffy.chen@rock-chips.com, Douglas Anderson , anton.wuerfel@fau.de, linux-rockchip@lists.infradead.org, eric.gao@rock-chips.com, phillip.raffeck@fau.de, tthayer@opensource.altera.com, linux-serial@vger.kernel.org, matwey@sai.msu.ru, andriy.shevchenko@linux.intel.com MIME-Version: 1.0 Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP On a Rockchip rk3399-based board during suspend/resume testing, we found that we could get the console UART into a state where it would print this to the console a lot: serial8250: too much work for irq42 Followed eventually by: NMI watchdog: BUG: soft lockup - CPU#0 stuck for 11s! Upon debugging I found that we're in this state: iir = 0x000000cc lsr = 0x00000060 It appears that somehow we have a RX Timeout interrupt but there is no actual data present to receive. When we're in this state the UART driver claims that it handled the interrupt but it actually doesn't really do anything. This means that we keep getting the interrupt over and over again. Normally we don't actually need to do anything special to handle a RX Timeout interrupt. We'll notice that there is some data ready and we'll read it, which will end up clearing the RX Timeout. In this case we have a problem specifically because we got the RX TImeout without any data. Reading a bogus byte is confirmed to get us out of this state. It's unclear how exactly the UART got into this state, but it is known that the UART lines are essentially undriven and unpowered during suspend, so possibly during resume some garbage / half transmitted bits are seen on the line and put the UART into this state. The UART on the rk3399 is a DesignWare based 8250 UART but I have placed this fix in the general 8250 code because it shouldn't hurt to have this detection on all 8250 UARTs and it's plausible some other UART could get into the same state. If these two extra lines of code are too much overhead, we can certainly move it into the DesignWare driver or even only do it for Rockchip UARTs. Signed-off-by: Douglas Anderson --- Testing and development done on a kernel-4.4 based tree, then picked to ToT, where the code applied cleanly. drivers/tty/serial/8250/8250_port.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index fe4399b41df6..8582c068c3d1 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1824,6 +1824,12 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) if (status & (UART_LSR_DR | UART_LSR_BI)) { if (!up->dma || handle_rx_dma(up, iir)) status = serial8250_rx_chars(up, status); + } else if ((iir & 0x3f) == UART_IIR_RX_TIMEOUT) { + /* + * On some systems we saw the timeout interrupt even when + * there was no data ready. Do a bogus read to clear it. + */ + (void) serial_port_in(port, UART_RX); } serial8250_modem_status(up); if ((!up->dma || up->dma->tx_err) && (status & UART_LSR_THRE))