Received: by 10.213.65.68 with SMTP id h4csp1762433imn; Mon, 19 Mar 2018 12:33:25 -0700 (PDT) X-Google-Smtp-Source: AG47ELsamxbp+e0nlNUMdPAl2x1d5przJh4/QNKYFZdND9B5RKO1YAzlN89P/v8ilAfZgJttvNvj X-Received: by 10.99.106.202 with SMTP id f193mr10186572pgc.334.1521488005102; Mon, 19 Mar 2018 12:33:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521488005; cv=none; d=google.com; s=arc-20160816; b=vUTI10qMyHEt+hY15Et9/UzUJZ+ES9/u/n4u8wvfE6OgdAnnEoXOfnDLgAi0R8XbDT Ij2Kx1XR07B9OWynhhW8jM8kUOIL7fDWShzRFuqJl1DXI+BXlLhtXg/27/ghh1g6ZwsL QcrykvS8F1tAoekPZX3hyk3EETwzrkhMMjqQ6Xd/Pp9Jz5XVRlouw7sDZjRSW+B24Jah I5crywIc1pgK0POCwHtYaxpfihiYBp/57YX7Zhda87J0iArgxSVAOE0FTe+sU8Q2JsL8 DQcuugBH+R/uPg652rIhs4Jy1Ub762bXxP0ClR/Y4qYwTB+chicl2EBvG00sTcN865ax lM1Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=mU0gPA9ouPF3HyrcC8f/W8sE2CaNgjeH00POqP6XuFA=; b=xdhpq6GRv32b5BsTZ4dzlRMjfiCr/d/2zTfHtn1MvJfhfUB5/M7vlnxXPO7VdwORX2 AqSj+DlImD37YGTrMnnh5ZB3c91KYdFAg3J8/lCN5VzexR5HKo3FkMdQ8d2aLgDTZOvF VB1ENhtNWTsOhsSjgFlh+OaV3ziRZyW9GrglShbpYN6P0KbCnVSdAnUiUvX0b8/HN0Sm I5cSUuUDkA5XJRehNAlztyjJ+SSj8GNtzdm8W53ePMcVsyaNHq8oF2SxTIzYxhuGkuTD VGgaXzW33ghk3jEerPKeGb38KWjfJS4nnJZ+TW1rd5HGBOK92x9bJq5kmQHhqMlQoAkN bl/w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n2-v6si560363pls.497.2018.03.19.12.33.10; Mon, 19 Mar 2018 12:33:25 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S968711AbeCSTbV (ORCPT + 99 others); Mon, 19 Mar 2018 15:31:21 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:49528 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1031074AbeCSSXg (ORCPT ); Mon, 19 Mar 2018 14:23:36 -0400 Received: from localhost (LFbn-1-12247-202.w90-92.abo.wanadoo.fr [90.92.61.202]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 4F491D09; Mon, 19 Mar 2018 18:23:35 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jayachandran C , Sasha Levin Subject: [PATCH 4.9 127/241] tty: amba-pl011: Fix spurious TX interrupts Date: Mon, 19 Mar 2018 19:06:32 +0100 Message-Id: <20180319180756.456254569@linuxfoundation.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180319180751.172155436@linuxfoundation.org> References: <20180319180751.172155436@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.9-stable review patch. If anyone has any objections, please let me know. ------------------ From: Jayachandran C [ Upstream commit 7d05587c9e0e4611650bb403812e2d492c178a9f ] On SMP systems, we see a lot of spurious TX interrupts when a program generates a steady stream of output to the pl011 UART. The problem can be easily seen when one CPU generates the output while another CPU handles the pl011 interrupts, and the rate of output is low enough not to fill the TX FIFO. The problem seems to be: -- CPU a -- -- CPU b -- (take port lock) pl011_start_tx pl011_start_tx_pio enable TXIM in REG_IMSC -> causes uart tx intr (pl011_int) pl011_tx_chars pl011_int ...tx chars, all done... (wait for port lock) pl011_stop_tx . disable TXIM . (release port lock) -> (take port lock) check for TXIM, not enabled (release port lock) return IRQ_NONE Enabling the TXIM in pl011_start_tx_pio() causes the interrupt to be generated and delivered to CPU b, even though pl011_tx_chars() is able to complete the TX and then disable the tx interrupt. Fix this by enabling TXIM only after pl011_tx_chars, if it is needed. pl011_tx_chars will return a boolean indicating whether the TX interrupts have to be enabled. Debugged-by: Vijaya Kumar Signed-off-by: Jayachandran C Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1302,14 +1302,15 @@ static void pl011_stop_tx(struct uart_po pl011_dma_tx_stop(uap); } -static void pl011_tx_chars(struct uart_amba_port *uap, bool from_irq); +static bool pl011_tx_chars(struct uart_amba_port *uap, bool from_irq); /* Start TX with programmed I/O only (no DMA) */ static void pl011_start_tx_pio(struct uart_amba_port *uap) { - uap->im |= UART011_TXIM; - pl011_write(uap->im, uap, REG_IMSC); - pl011_tx_chars(uap, false); + if (pl011_tx_chars(uap, false)) { + uap->im |= UART011_TXIM; + pl011_write(uap->im, uap, REG_IMSC); + } } static void pl011_start_tx(struct uart_port *port) @@ -1389,25 +1390,26 @@ static bool pl011_tx_char(struct uart_am return true; } -static void pl011_tx_chars(struct uart_amba_port *uap, bool from_irq) +/* Returns true if tx interrupts have to be (kept) enabled */ +static bool pl011_tx_chars(struct uart_amba_port *uap, bool from_irq) { struct circ_buf *xmit = &uap->port.state->xmit; int count = uap->fifosize >> 1; if (uap->port.x_char) { if (!pl011_tx_char(uap, uap->port.x_char, from_irq)) - return; + return true; uap->port.x_char = 0; --count; } if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) { pl011_stop_tx(&uap->port); - return; + return false; } /* If we are using DMA mode, try to send some characters. */ if (pl011_dma_tx_irq(uap)) - return; + return true; do { if (likely(from_irq) && count-- == 0) @@ -1422,8 +1424,11 @@ static void pl011_tx_chars(struct uart_a if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&uap->port); - if (uart_circ_empty(xmit)) + if (uart_circ_empty(xmit)) { pl011_stop_tx(&uap->port); + return false; + } + return true; } static void pl011_modem_status(struct uart_amba_port *uap)