From patchwork Sun Nov 24 15:43:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leo Yan X-Patchwork-Id: 11259223 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 529801390 for ; Sun, 24 Nov 2019 15:44:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 276EC2073F for ; Sun, 24 Nov 2019 15:44:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="gcN26IH2" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726680AbfKXPn7 (ORCPT ); Sun, 24 Nov 2019 10:43:59 -0500 Received: from mail-yb1-f194.google.com ([209.85.219.194]:37965 "EHLO mail-yb1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725989AbfKXPn7 (ORCPT ); Sun, 24 Nov 2019 10:43:59 -0500 Received: by mail-yb1-f194.google.com with SMTP id k206so4987119ybb.5 for ; Sun, 24 Nov 2019 07:43:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=7GoVKZppoRs4H8MV5EKljB+lt4NwFU2QYQ4kHf9aeFM=; b=gcN26IH29ommNyDhhBdS4LUjBSrhnXAY5ZK1+Yfk+Ut2ikTr3yycJPIH/+RCBpTxej N3TJayJ955EbCu045tGM2rEeL1myhqCn4BIxYOU16q0Shyq0hjbSHBw/MRfXxxVnzG2a hoiIRe8KalUW2+Fl4zEqdIbGYkOibTEl4kdeDcDIM9ExUeU8to+bnMXaGRqKOFlooUmy OWxikAkr9yZ/fEAc3KUdjeUrD7Tzb78Z4PkiftSuvzZAtAvNtPDacWCgA+Kyxle6eoo2 H4tCC/DHHg6AbTdmSWPMpy8WHZHMZBfOfC2TZhYTLcO3OoW0VYxhjd/iz+a8H9oY7niu m3XA== 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=7GoVKZppoRs4H8MV5EKljB+lt4NwFU2QYQ4kHf9aeFM=; b=OHrfAnRh6FsTztdjjugMZs83l9XMwhTNQP/sSTS0q2Tp3MUQm3yVI3/Oa8hjA5fQfQ TpbTj32DlS5WvUQfKFj+/l0DHOfn5PDeKunPQX99Hfhi2fy5i+Lwf3W+TnvEh+5EcFXT FQU7RNCD4+v5pvC8xvCg6pf/MEa5QY+dZQNJhDFHSC9lqv83KpauSUalQMjEWvXIlyn+ 3R1qQBeHMpY1Cs2hfLB0SLOHW7pXWW5fk9Stq7u7HlFExA7uDFzaG11knvuVymhgEFIM NV8vq9n1+ALEDVQeVkzqxvCYwkW2/7Eis9/oSrbjA764rd9bkQ91Mn50WhYOpSbuwrm+ cggg== X-Gm-Message-State: APjAAAW6UTRosFyNTMOkk3X1QcQGdeg17WlXj5YjzxG2Ru+Vd/7Dt41k Q1ounj/IXDmxC9PIxNNeYuU5aQ== X-Google-Smtp-Source: APXvYqyEZRjk614ciccDP+789BFWvngD1xEZFN1RKPsZLP+LMRQQPwNkhHtc3XCbgw+xJQsROxYehg== X-Received: by 2002:a25:8281:: with SMTP id r1mr19218080ybk.489.1574610237279; Sun, 24 Nov 2019 07:43:57 -0800 (PST) Received: from localhost.localdomain (li2093-158.members.linode.com. [172.105.159.158]) by smtp.gmail.com with ESMTPSA id h81sm2222564ywa.78.2019.11.24.07.43.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 24 Nov 2019 07:43:56 -0800 (PST) From: Leo Yan To: Andy Gross , Greg Kroah-Hartman , Jiri Slaby , Bjorn Andersson , Stephen Boyd , Nicolas Dechesne , linux-arm-msm@vger.kernel.org, linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Leo Yan Subject: [PATCH 1/2] tty: serial: msm_serial: Fix lockup for sysrq and oops Date: Sun, 24 Nov 2019 23:43:33 +0800 Message-Id: <20191124154334.15366-1-leo.yan@linaro.org> X-Mailer: git-send-email 2.17.1 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org As the commit 677fe555cbfb ("serial: imx: Fix recursive locking bug") has mentioned the uart driver might cause recursive locking between normal printing and the kernel debugging facilities (e.g. sysrq and oops). In the commit it gave out suggestion for fixing recursive locking issue: "The solution is to avoid locking in the sysrq case and trylock in the oops_in_progress case." This patch follows the suggestion (also used the exactly same code with other serial drivers, e.g. amba-pl011.c) to fix the recursive locking issue, this can avoid stuck caused by deadlock and print out log for sysrq and oops. Signed-off-by: Leo Yan --- drivers/tty/serial/msm_serial.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 3657a24913fc..889538182e83 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -1576,6 +1576,7 @@ static void __msm_console_write(struct uart_port *port, const char *s, int num_newlines = 0; bool replaced = false; void __iomem *tf; + int locked = 1; if (is_uartdm) tf = port->membase + UARTDM_TF; @@ -1588,7 +1589,13 @@ static void __msm_console_write(struct uart_port *port, const char *s, num_newlines++; count += num_newlines; - spin_lock(&port->lock); + if (port->sysrq) + locked = 0; + else if (oops_in_progress) + locked = spin_trylock(&port->lock); + else + spin_lock(&port->lock); + if (is_uartdm) msm_reset_dm_count(port, count); @@ -1624,7 +1631,9 @@ static void __msm_console_write(struct uart_port *port, const char *s, iowrite32_rep(tf, buf, 1); i += num_chars; } - spin_unlock(&port->lock); + + if (locked) + spin_unlock(&port->lock); } static void msm_console_write(struct console *co, const char *s, From patchwork Sun Nov 24 15:43:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leo Yan X-Patchwork-Id: 11259225 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 92273930 for ; Sun, 24 Nov 2019 15:44:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 688542073F for ; Sun, 24 Nov 2019 15:44:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="nh+CvKWE" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726792AbfKXPoE (ORCPT ); Sun, 24 Nov 2019 10:44:04 -0500 Received: from mail-yw1-f65.google.com ([209.85.161.65]:34095 "EHLO mail-yw1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726775AbfKXPoE (ORCPT ); Sun, 24 Nov 2019 10:44:04 -0500 Received: by mail-yw1-f65.google.com with SMTP id l14so1713126ywh.1 for ; Sun, 24 Nov 2019 07:44:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=GqQQ8sAnCYygNP94HJPDN0z12tYLH4hLXTaPwjkO9+w=; b=nh+CvKWEoocTUrSe/I48NOPbqzjjzQmkgbEoRWg8dOwwTRVeUULRRO1wGLj8dFX33D mdJJ4ssRJhV66a4TqHsFKV8Saq1KbocEVBCtv8nBv1Yf1fsBxga1r5fxBgVq/UfqsSfa 9yGxhlFlUUWi3rwFaLFwHLCwjj4mvtvNofc2bzk3fDYBNRVmwRZKQDBRjIuRP4mYsH9O tOjsi4vzdN3SirpEuvVuapfoISnOZX1uDkOMpYL1S0ahQyLZfilYi6rztySsfSHMAgia vrqwt0HknnOXHhQj6OwyI06jwL2MxHrjcne19ifUni014Dl/LOcQE4iTJwrvJe6GSleS Gu7w== 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:in-reply-to :references; bh=GqQQ8sAnCYygNP94HJPDN0z12tYLH4hLXTaPwjkO9+w=; b=VTA13nzRUMKpI+mzUfhX5junrLjXsONUF+ufUpcdRW1BuggeVq5+6Lha8B+2dYZZn+ 80IeUYJ0beVZp8UKZBQMF9dQeHN0oykWKucx3DC1zCG01mxxy51ZNY35KN0AGBI1OAb3 AmAbc1/4dlqfpTwWmmpKYq+3GHSV0MqLRWgZSbJFPc1tKy/7aEWJjRdP9M6QNmrC+/Z0 BlXDz3MGYkuQspTw9IYKNO0YzesIOPsFQY5yuM13XULaffkIb3Pfdrxto31a1+lH8Lfl PtrJ1ygGFNmsW7nXcXjz1mcI37oAnue/01AqTLiSszXYKf46dbnp5XEER2pCW+XjhBYb 74CQ== X-Gm-Message-State: APjAAAVo1wazNg/RxpvM9xfAyP9e616I5pCf4OHrg6GLrCDpXymVaCPB dPPeBJ2nXfcWZ84FMVxHNUT6VQ== X-Google-Smtp-Source: APXvYqzQMxNKBRsdGeSsn/59/PqlcKP9o5gQMIaZahjp75Xr5m/pW3qW4Nev8c/uGw8zj0uQ7+OhAA== X-Received: by 2002:a0d:d651:: with SMTP id y78mr16840971ywd.365.1574610243206; Sun, 24 Nov 2019 07:44:03 -0800 (PST) Received: from localhost.localdomain (li2093-158.members.linode.com. [172.105.159.158]) by smtp.gmail.com with ESMTPSA id h81sm2222564ywa.78.2019.11.24.07.43.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 24 Nov 2019 07:44:02 -0800 (PST) From: Leo Yan To: Andy Gross , Greg Kroah-Hartman , Jiri Slaby , Bjorn Andersson , Stephen Boyd , Nicolas Dechesne , linux-arm-msm@vger.kernel.org, linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Leo Yan Subject: [PATCH 2/2] tty: serial: msm_serial: Fix deadlock caused by recursive output Date: Sun, 24 Nov 2019 23:43:34 +0800 Message-Id: <20191124154334.15366-2-leo.yan@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191124154334.15366-1-leo.yan@linaro.org> References: <20191124154334.15366-1-leo.yan@linaro.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org The uart driver might run into deadlock caused by recursive output; the basic flow is after uart driver has acquired the port spinlock, then it invokes some functions, e.g. dma engine operations and allocate dma descriptor with kzalloc(), if the system has very less free memory, the kernel will give out warning by printing logs, thus recursive output will happen and at the second time the attempting to acquire lock will cause deadlock. The detailed flow is shown as below: msm_uart_irq() spin_lock_irqsave(&port->lock, flags) => First time to acquire lock msm_handle_tx(port) msm_handle_tx_dma() dmaengine_prep_slave_single() bam_prep_slave_sg() kzalloc() __kmalloc() ___slab_alloc() alloc_pages_current() __alloc_pages_nodemask() warn_alloc() printk() msm_console_write() __msm_console_write() spin_lock(&port->lock) => Cause deadlock This patch fixes the deadlock issue for recursive output; it adds a variable 'curr_user' to indicate the uart port is used by which CPU, if the CPU has acquired spinlock and wants to execute recursive output, it will directly bail out. Here we don't choose to avoid locking and print out log, the reason is in this case we don't want to reset the uart port with function msm_reset_dm_count(); otherwise it can introduce confliction with other flows and results in uart port malfunction and later cannot output anymore. Signed-off-by: Leo Yan --- drivers/tty/serial/msm_serial.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 889538182e83..06076cd2948f 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -182,6 +182,7 @@ struct msm_port { bool break_detected; struct msm_dma tx_dma; struct msm_dma rx_dma; + struct cpumask curr_user; }; #define UART_TO_MSM(uart_port) container_of(uart_port, struct msm_port, uart) @@ -436,6 +437,7 @@ static void msm_complete_tx_dma(void *args) u32 val; spin_lock_irqsave(&port->lock, flags); + cpumask_set_cpu(smp_processor_id(), &msm_port->curr_user); /* Already stopped */ if (!dma->count) @@ -470,6 +472,7 @@ static void msm_complete_tx_dma(void *args) msm_handle_tx(port); done: + cpumask_clear_cpu(smp_processor_id(), &msm_port->curr_user); spin_unlock_irqrestore(&port->lock, flags); } @@ -544,6 +547,7 @@ static void msm_complete_rx_dma(void *args) u32 val; spin_lock_irqsave(&port->lock, flags); + cpumask_set_cpu(smp_processor_id(), &msm_port->curr_user); /* Already stopped */ if (!dma->count) @@ -590,6 +594,7 @@ static void msm_complete_rx_dma(void *args) msm_start_rx_dma(msm_port); done: + cpumask_clear_cpu(smp_processor_id(), &msm_port->curr_user); spin_unlock_irqrestore(&port->lock, flags); if (count) @@ -931,6 +936,7 @@ static irqreturn_t msm_uart_irq(int irq, void *dev_id) u32 val; spin_lock_irqsave(&port->lock, flags); + cpumask_set_cpu(smp_processor_id(), &msm_port->curr_user); misr = msm_read(port, UART_MISR); msm_write(port, 0, UART_IMR); /* disable interrupt */ @@ -962,6 +968,7 @@ static irqreturn_t msm_uart_irq(int irq, void *dev_id) msm_handle_delta_cts(port); msm_write(port, msm_port->imr, UART_IMR); /* restore interrupt */ + cpumask_clear_cpu(smp_processor_id(), &msm_port->curr_user); spin_unlock_irqrestore(&port->lock, flags); return IRQ_HANDLED; @@ -1572,6 +1579,7 @@ static inline struct uart_port *msm_get_port_from_line(unsigned int line) static void __msm_console_write(struct uart_port *port, const char *s, unsigned int count, bool is_uartdm) { + struct msm_port *msm_port = UART_TO_MSM(port); int i; int num_newlines = 0; bool replaced = false; @@ -1593,6 +1601,8 @@ static void __msm_console_write(struct uart_port *port, const char *s, locked = 0; else if (oops_in_progress) locked = spin_trylock(&port->lock); + else if (cpumask_test_cpu(smp_processor_id(), &msm_port->curr_user)) + return; else spin_lock(&port->lock);