From patchwork Wed Dec 7 19:59:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 13067569 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 88D48C63708 for ; Wed, 7 Dec 2022 20:00:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=frLB0QrGtlpAm6gWTirTTJHhzjfvuwz3+Z5h8/yKpJ4=; b=aLA74ZiuVqHhy3 xra8wFzonGV7sx0NmqJcH2Bpqh7HS4ypMe8qBJPEZFH9t6aBGe63EPXsRli2xPB2w5R/FrAxzVAyK dAXyLu0PGVcQWRjyKSD9KhFOJFyNYNJYB61snMq9huODWW1AZihg2TvPg68hb2ejAQTW5BK3exSZq c5WbRkhrFHaLo2SoSFd1bPNO/uSo74AilVqE/JBA00x4IheBXrcWvUTt0YEs3blfsg2xAL65REpRP N0MFMx0rnv5BtpKpOeps3uy3gKmozWNy2HjxSOYB9yE4t1F40p2ZDD1w8G2ue0U3csftDme7Butpk uHXt7KWwZaN/zbqeDmnQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1p30a5-00BS3C-TC; Wed, 07 Dec 2022 19:59:50 +0000 Received: from phobos.denx.de ([2a01:238:438b:c500:173d:9f52:ddab:ee01]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1p30a3-00BRlG-5o for linux-arm-kernel@lists.infradead.org; Wed, 07 Dec 2022 19:59:49 +0000 Received: from tr.lan (ip-86-49-120-218.bb.vodafone.cz [86.49.120.218]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: marex@denx.de) by phobos.denx.de (Postfix) with ESMTPSA id 9757880077; Wed, 7 Dec 2022 20:59:43 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=phobos-20191101; t=1670443184; bh=diOPNo3NDanw1+A2lM8NqOPrWQC5XsQ3uf6wn4oIlyk=; h=From:To:Cc:Subject:Date:From; b=ATH6UsVLgl/aL5uGQ0bPdDwRifCve0saE9ZSW6Rbaw1Sidxw9bwNcUkt4DdUEJzIc FsiWzjSdzwILC7WCQOvJ2Q/qMCS/TF/eSnVfGtwYnUdFFqVIox7xrV4D2NAQVZ4d1u hYa3dcTx0NGN1AhWkBCse2mS/BHZjeglR9XEL2Sd5cjC2Pm2WIuIpjY6EmrB/FeX/o p+qF8O6W0qZfNppquVbHiquT/mtW2m5RbClFi0sXYmMf9YdLdg0DkJL9J/dDc+csCk u4dQN5RY4s1mtlhke/BL7DwjogTLjItTUaHUr2PUoXkeOVjuMVnspZMnbNOyZsq6a0 m1H7ogs/53TuA== From: Marek Vasut To: linux-serial@vger.kernel.org Cc: Marek Vasut , Alexandre Torgue , Erwan Le Ray , Greg Kroah-Hartman , Jean Philippe Romain , Jiri Slaby , Maxime Coquelin , Sebastian Andrzej Siewior , Thomas Gleixner , Valentin Caron , linux-arm-kernel@lists.infradead.org, linux-stm32@st-md-mailman.stormreply.com Subject: [PATCH] serial: stm32: Move hard IRQ handling to threaded interrupt context Date: Wed, 7 Dec 2022 20:59:29 +0100 Message-Id: <20221207195929.160267-1-marex@denx.de> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221207_115947_647887_C08EA243 X-CRM114-Status: GOOD ( 15.80 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Avoid locking in hard interrupt context, move the entirety of hard IRQ context code into the threaded IRQ handler. This fixes the following splat with preempt-rt enabled: BUG: scheduling while atomic: (mount)/1289/0x00010001 Modules linked in: Preemption disabled at: [] irq_enter_rcu+0xb/0x42 CPU: 0 PID: 1289 Comm: (mount) Not tainted 6.1.0-rc7-rt5-stable-standard-00006-gd70aeccb9f0f #17 Hardware name: STM32 (Device Tree Support) unwind_backtrace from show_stack+0xb/0xc show_stack from dump_stack_lvl+0x2b/0x34 dump_stack_lvl from __schedule_bug+0x53/0x80 __schedule_bug from __schedule+0x47/0x404 __schedule from schedule_rtlock+0x15/0x34 schedule_rtlock from rtlock_slowlock_locked+0x1d7/0x57e rtlock_slowlock_locked from rt_spin_lock+0x29/0x3c rt_spin_lock from stm32_usart_interrupt+0xa9/0x110 stm32_usart_interrupt from __handle_irq_event_percpu+0x73/0x14e __handle_irq_event_percpu from handle_irq_event_percpu+0x9/0x22 handle_irq_event_percpu from handle_irq_event+0x53/0x76 handle_irq_event from handle_fasteoi_irq+0x65/0xa8 handle_fasteoi_irq from handle_irq_desc+0xf/0x18 handle_irq_desc from gic_handle_irq+0x45/0x54 gic_handle_irq from generic_handle_arch_irq+0x19/0x2c generic_handle_arch_irq from call_with_stack+0xd/0x10 Signed-off-by: Marek Vasut --- Cc: Alexandre Torgue Cc: Erwan Le Ray Cc: Greg Kroah-Hartman Cc: Jean Philippe Romain Cc: Jiri Slaby Cc: Maxime Coquelin Cc: Sebastian Andrzej Siewior Cc: Thomas Gleixner Cc: Valentin Caron Cc: linux-arm-kernel@lists.infradead.org Cc: linux-stm32@st-md-mailman.stormreply.com To: linux-serial@vger.kernel.org --- drivers/tty/serial/stm32-usart.c | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index a1490033aa164..f5bce0be02676 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -745,14 +745,15 @@ static void stm32_usart_transmit_chars(struct uart_port *port) } } -static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) +static irqreturn_t stm32_usart_threaded_interrupt(int irq, void *ptr) { struct uart_port *port = ptr; struct tty_port *tport = &port->state->port; struct stm32_port *stm32_port = to_stm32_port(port); const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; - u32 sr; + unsigned long flags; unsigned int size; + u32 sr; sr = readl_relaxed(port->membase + ofs->isr); @@ -792,27 +793,13 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) } if ((sr & USART_SR_TXE) && !(stm32_port->tx_ch)) { - spin_lock(&port->lock); + spin_lock_irqsave(&port->lock, flags); stm32_usart_transmit_chars(port); - spin_unlock(&port->lock); + spin_unlock_irqrestore(&port->lock, flags); } - if (stm32_usart_rx_dma_enabled(port)) - return IRQ_WAKE_THREAD; - else - return IRQ_HANDLED; -} - -static irqreturn_t stm32_usart_threaded_interrupt(int irq, void *ptr) -{ - struct uart_port *port = ptr; - struct tty_port *tport = &port->state->port; - struct stm32_port *stm32_port = to_stm32_port(port); - unsigned int size; - unsigned long flags; - /* Receiver timeout irq for DMA RX */ - if (!stm32_port->throttled) { + if (stm32_usart_rx_dma_enabled(port) && !stm32_port->throttled) { spin_lock_irqsave(&port->lock, flags); size = stm32_usart_receive_chars(port, false); uart_unlock_and_check_sysrq_irqrestore(port, flags); @@ -1015,7 +1002,7 @@ static int stm32_usart_startup(struct uart_port *port) u32 val; int ret; - ret = request_threaded_irq(port->irq, stm32_usart_interrupt, + ret = request_threaded_irq(port->irq, NULL, stm32_usart_threaded_interrupt, IRQF_ONESHOT | IRQF_NO_SUSPEND, name, port);