Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932980AbcLGUGv (ORCPT ); Wed, 7 Dec 2016 15:06:51 -0500 Received: from mout.gmx.net ([212.227.17.22]:50075 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932568AbcLGUGS (ORCPT ); Wed, 7 Dec 2016 15:06:18 -0500 From: Lino Sanfilippo To: bh74.an@samsung.com, ks.giri@samsung.com, vipul.pandya@samsung.com, peppe.cavallaro@st.com, alexandre.torgue@st.com Cc: pavel@ucw.cz, davem@davemloft.net, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Lino Sanfilippo Subject: [PATCH 2/2] net: ethernet: stmmac: remove private tx queue lock Date: Wed, 7 Dec 2016 21:05:38 +0100 Message-Id: <1481141138-19466-3-git-send-email-LinoSanfilippo@gmx.de> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1481141138-19466-1-git-send-email-LinoSanfilippo@gmx.de> References: <1481141138-19466-1-git-send-email-LinoSanfilippo@gmx.de> X-Provags-ID: V03:K0:gNhfgM4YYviGwkQxbIeoiu19EfALKoOqaf4SopkTWBdyTv2au6h s6843iXv54HDRlPs1QPr3CvfSqZ9y5AC6FRdvY5hanYyRCmb7Nma6aTfBnSyOB0LPRDgObx 35SBGhEZ9IHDcy43bZpO7R/+HI3c5ytRz4AkM74SZP5mINvH7X9C9mpgdfl0KqC/ulbfd8Z g9U4blIl2QfSGfrSpeDZw== X-UI-Out-Filterresults: notjunk:1;V01:K0:My218HFPjlg=:8IQ6Ha6L5AkpF6gW0mPsCn QmeUl++Y2vW+qhz0V3S752tADhpRKJf35CVc40vAqVA1/Q4S1+HddSlte881PRrsipW3o9JDz 2dq0w5OfYHBP/CwqeuxyWJNzxwTGY0fqNWsqDPwzah3uE4j7Q6cAWYy/eCCeJ989Mfs1dYj4d 6rn3vu8bhx+K5PVCRD03tbWFbwfbZCWdBpL5DaW5YGz2IVgjI0wOkv/O4ZhTGslwoqBwfMJ1L CLhsQb0My/hjB0T2trTW21gdKqQXci2OZUx627FsCEaJZgXj68dGxsc5AS6u+6upWYulEpYWy FeCbnjdDGeOUuP61MPoqvDd8RvkZmAAFpDlstO81uhjBmmhaQyIJmyheA6B1NLEF8NlwBq6fT FZq1ZSZ81Od+CgTlU2lNez10jZvkRJQbVOm//DXLm26aCTTLEvQVyFhupA1vf+myM/S3lqxWS I8AxsSOMy8Uw+rDQiQnFORsxE1oyLRAFUm56SXp1pp6v8alKQ8mqKfEQ5HW60dN3RGRPJnEIf JJJi+5sTTz3qZr1MutlC5Tke1dnygIp//Ekt6Wk0KY/NtQHpE9w1rkNsVkSsr1xCsap1Z3lPF ZsorIgzVL3ZKK9nGjneunZEsE5ycJ8bjhIyZaELspnBtHL+Uq8aOaCXGXon3gAMNGZQnzJHVo 2doHW50P/RgFlS6cIZ+Ws7bK2otEsCaMC5bWPMNjkLKTASpMdpo3MuOAVTu40q1DRBUvlj+fR 1b8QqdFBuMfn8QWpXcJf0ECC8HnFaTLNS9zAVpKLGc1nNrfKcAx+fBa6dBo= Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4767 Lines: 133 The driver uses a private lock for synchronization between the xmit function and the xmit completion handler, but since the NETIF_F_LLTX flag is not set, the xmit function is also called with the xmit_lock held. On the other hand the xmit completion handler first takes the private lock and (in case that the tx queue has been stopped) the xmit_lock, leading to a reverse locking order and the potential danger of a deadlock. Fix this by removing the private lock completely and synchronizing the xmit function and completion handler solely by means of the xmit_lock. By doing this remove also the now unnecessary double check for a stopped tx queue. Signed-off-by: Lino Sanfilippo --- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 - drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 28 +++++------------------ 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 4d2a759..7e69b11 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -64,7 +64,6 @@ struct stmmac_priv { dma_addr_t dma_tx_phy; int tx_coalesce; int hwts_tx_en; - spinlock_t tx_lock; bool tx_path_in_lpi_mode; struct timer_list txtimer; bool tso; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index caf069a..db46ec4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1307,7 +1307,7 @@ static void stmmac_tx_clean(struct stmmac_priv *priv) unsigned int bytes_compl = 0, pkts_compl = 0; unsigned int entry = priv->dirty_tx; - spin_lock(&priv->tx_lock); + netif_tx_lock(priv->dev); priv->xstats.tx_clean++; @@ -1378,22 +1378,17 @@ static void stmmac_tx_clean(struct stmmac_priv *priv) netdev_completed_queue(priv->dev, pkts_compl, bytes_compl); if (unlikely(netif_queue_stopped(priv->dev) && - stmmac_tx_avail(priv) > STMMAC_TX_THRESH)) { - netif_tx_lock(priv->dev); - if (netif_queue_stopped(priv->dev) && - stmmac_tx_avail(priv) > STMMAC_TX_THRESH) { - if (netif_msg_tx_done(priv)) - pr_debug("%s: restart transmit\n", __func__); - netif_wake_queue(priv->dev); - } - netif_tx_unlock(priv->dev); + stmmac_tx_avail(priv) > STMMAC_TX_THRESH)) { + if (netif_msg_tx_done(priv)) + pr_debug("%s: restart transmit\n", __func__); + netif_wake_queue(priv->dev); } if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) { stmmac_enable_eee_mode(priv); mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer)); } - spin_unlock(&priv->tx_lock); + netif_tx_unlock(priv->dev); } static inline void stmmac_enable_dma_irq(struct stmmac_priv *priv) @@ -1998,8 +1993,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) u8 proto_hdr_len; int i; - spin_lock(&priv->tx_lock); - /* Compute header lengths */ proto_hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); @@ -2011,7 +2004,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) /* This is a hard error, log it. */ pr_err("%s: Tx Ring full when queue awake\n", __func__); } - spin_unlock(&priv->tx_lock); return NETDEV_TX_BUSY; } @@ -2146,11 +2138,9 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) priv->hw->dma->set_tx_tail_ptr(priv->ioaddr, priv->tx_tail_addr, STMMAC_CHAN0); - spin_unlock(&priv->tx_lock); return NETDEV_TX_OK; dma_map_err: - spin_unlock(&priv->tx_lock); dev_err(priv->device, "Tx dma map failed\n"); dev_kfree_skb(skb); priv->dev->stats.tx_dropped++; @@ -2182,10 +2172,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) return stmmac_tso_xmit(skb, dev); } - spin_lock(&priv->tx_lock); - if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) { - spin_unlock(&priv->tx_lock); if (!netif_queue_stopped(dev)) { netif_stop_queue(dev); /* This is a hard error, log it. */ @@ -2357,11 +2344,9 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) priv->hw->dma->set_tx_tail_ptr(priv->ioaddr, priv->tx_tail_addr, STMMAC_CHAN0); - spin_unlock(&priv->tx_lock); return NETDEV_TX_OK; dma_map_err: - spin_unlock(&priv->tx_lock); dev_err(priv->device, "Tx dma map failed\n"); dev_kfree_skb(skb); priv->dev->stats.tx_dropped++; @@ -3347,7 +3332,6 @@ int stmmac_dvr_probe(struct device *device, netif_napi_add(ndev, &priv->napi, stmmac_poll, 64); spin_lock_init(&priv->lock); - spin_lock_init(&priv->tx_lock); ret = register_netdev(ndev); if (ret) { -- 1.9.1