Received: by 2002:a25:d783:0:0:0:0:0 with SMTP id o125csp658690ybg; Thu, 19 Mar 2020 06:32:52 -0700 (PDT) X-Google-Smtp-Source: ADFU+vuhDCIM37oxm4yAXJfeCvyMA4rUDYun8IpZGTvxc/+gn89Y7vQzrZGinuTfzvu7iliIk94P X-Received: by 2002:a9d:4d0c:: with SMTP id n12mr2408481otf.83.1584624772665; Thu, 19 Mar 2020 06:32:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1584624772; cv=none; d=google.com; s=arc-20160816; b=y03wKAlXfZjJfuIcDlqS/kTt8TKGHzFOUOX0zc8vINSbQlKaPoZKTPZKLQ2MmXsMUO y20xw8szHvb6Y2wJFkoZEaHMEIYe4hHewx7BHcavN6imCyFXNwAsuvqqm2nyHb0nShTF 9DdmnMDi/kuuRTY2OzGafNURJYD0lpMH2C/yxBVD2rpI8IuKD0EEe7EOctZlGH16AmI+ g5kV+a8JiAIX+PJehbiawg0VSUKD4K/P1ENMcMMgs+FSBQB61S6aWWhH99SZ/WuQ0c/H jb9KOBDU32lhrXqM8AuOmNNxmb0HbYqztHYIDMCd6NyrI9eeHkLJXHt2qi6nBIUJGAV6 dwOQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=a+G+8hCyixEQNIWIgH+xj/WC7RE/PTIbpJeiMb4yM6I=; b=W0WeRqwqwxHhgO4xMVGJR/iUEeP0XJKid9FauVmajtQZUwHm3k3TsUOx+Lnu6xH606 8Q1sqLUPI3OqgCxdaSAJGUJohtVPwaFgvBIilDzYXdLi35m5Ma7cq6lbuLMBUlJHBEFu 5XQZKMSrfEy87zHqUMRhlU2LmRsMk/aC5RAWUOV99y2+lKGnYBtopiRLMXyW8jarf1RV q4nTK0BWNI3QBREa0tEEFfYLZBqeIHAQw5vrlZi/l1AH7Sur++nt9AMvj+RMdbZ193Oa TwVvoNKlWTjEAd59Pur3uLN3J3XBSaoz9rUyEuBkIe1Dp+5n2iTG1VNLrIuEBHo/J8J+ hsqA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=boK1Cof3; 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 m13si1239650otk.113.2020.03.19.06.32.38; Thu, 19 Mar 2020 06:32:52 -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; dkim=pass header.i=@kernel.org header.s=default header.b=boK1Cof3; 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 S1729766AbgCSNST (ORCPT + 99 others); Thu, 19 Mar 2020 09:18:19 -0400 Received: from mail.kernel.org ([198.145.29.99]:40254 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729751AbgCSNSP (ORCPT ); Thu, 19 Mar 2020 09:18:15 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 9384F216FD; Thu, 19 Mar 2020 13:18:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1584623894; bh=f/0NjRvnQjjY3mEN1mjcZeepfaexZaG30RrgdOTwJD0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=boK1Cof3Hn8gue6fvfslarJQ0QoFAi4PKhKKrTZWfwnFFi3WBKEl5i+ZxWdeA1q6m ehDiL2ZmgbT3+V4KeSXn5ZWi6YV1eo9DyoIxs423QH5GOVD2AWqVASpnmf24pOIjOs IcHHUMGgU9cPSrR+TFZlyJ1/ya07tmDJZyQhlywk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Marek Vasut , "David S. Miller" , Lukas Wunner , Petr Stetiar , YueHaibing , Sasha Levin Subject: [PATCH 4.14 89/99] net: ks8851-ml: Fix IRQ handling and locking Date: Thu, 19 Mar 2020 14:04:07 +0100 Message-Id: <20200319124006.692701889@linuxfoundation.org> X-Mailer: git-send-email 2.25.2 In-Reply-To: <20200319123941.630731708@linuxfoundation.org> References: <20200319123941.630731708@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Marek Vasut [ Upstream commit 44343418d0f2f623cb9da6f5000df793131cbe3b ] The KS8851 requires that packet RX and TX are mutually exclusive. Currently, the driver hopes to achieve this by disabling interrupt from the card by writing the card registers and by disabling the interrupt on the interrupt controller. This however is racy on SMP. Replace this approach by expanding the spinlock used around the ks_start_xmit() TX path to ks_irq() RX path to assure true mutual exclusion and remove the interrupt enabling/disabling, which is now not needed anymore. Furthermore, disable interrupts also in ks_net_stop(), which was missing before. Note that a massive improvement here would be to re-use the KS8851 driver approach, which is to move the TX path into a worker thread, interrupt handling to threaded interrupt, and synchronize everything with mutexes, but that would be a much bigger rework, for a separate patch. Signed-off-by: Marek Vasut Cc: David S. Miller Cc: Lukas Wunner Cc: Petr Stetiar Cc: YueHaibing Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/micrel/ks8851_mll.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c index 799154d7c0470..c699a779757eb 100644 --- a/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/drivers/net/ethernet/micrel/ks8851_mll.c @@ -831,14 +831,17 @@ static irqreturn_t ks_irq(int irq, void *pw) { struct net_device *netdev = pw; struct ks_net *ks = netdev_priv(netdev); + unsigned long flags; u16 status; + spin_lock_irqsave(&ks->statelock, flags); /*this should be the first in IRQ handler */ ks_save_cmd_reg(ks); status = ks_rdreg16(ks, KS_ISR); if (unlikely(!status)) { ks_restore_cmd_reg(ks); + spin_unlock_irqrestore(&ks->statelock, flags); return IRQ_NONE; } @@ -864,6 +867,7 @@ static irqreturn_t ks_irq(int irq, void *pw) ks->netdev->stats.rx_over_errors++; /* this should be the last in IRQ handler*/ ks_restore_cmd_reg(ks); + spin_unlock_irqrestore(&ks->statelock, flags); return IRQ_HANDLED; } @@ -933,6 +937,7 @@ static int ks_net_stop(struct net_device *netdev) /* shutdown RX/TX QMU */ ks_disable_qmu(ks); + ks_disable_int(ks); /* set powermode to soft power down to save power */ ks_set_powermode(ks, PMECR_PM_SOFTDOWN); @@ -989,10 +994,9 @@ static netdev_tx_t ks_start_xmit(struct sk_buff *skb, struct net_device *netdev) { netdev_tx_t retv = NETDEV_TX_OK; struct ks_net *ks = netdev_priv(netdev); + unsigned long flags; - disable_irq(netdev->irq); - ks_disable_int(ks); - spin_lock(&ks->statelock); + spin_lock_irqsave(&ks->statelock, flags); /* Extra space are required: * 4 byte for alignment, 4 for status/length, 4 for CRC @@ -1006,9 +1010,7 @@ static netdev_tx_t ks_start_xmit(struct sk_buff *skb, struct net_device *netdev) dev_kfree_skb(skb); } else retv = NETDEV_TX_BUSY; - spin_unlock(&ks->statelock); - ks_enable_int(ks); - enable_irq(netdev->irq); + spin_unlock_irqrestore(&ks->statelock, flags); return retv; } -- 2.20.1