From: Lino Sanfilippo <LinoSanfilippo@gmx.de>
To: Francois Romieu <romieu@fr.zoreil.com>, Pavel Machek <pavel@ucw.cz>
Cc: bh74.an@samsung.com, ks.giri@samsung.com,
vipul.pandya@samsung.com, peppe.cavallaro@st.com,
alexandre.torgue@st.com, davem@davemloft.net,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org
Subject: Re: [PATCH 1/2] net: ethernet: sxgbe: remove private tx queue lock
Date: Sun, 18 Dec 2016 17:15:10 +0100 [thread overview]
Message-ID: <a2cbcfcd-f377-565c-a21c-3daa3abce519@gmx.de> (raw)
In-Reply-To: <20161218001507.GA5343@electric-eye.fr.zoreil.com>
Hi,
On 18.12.2016 01:15, Francois Romieu wrote:
> Pavel Machek <pavel@ucw.cz> :
> [...]
>> Won't this up/down the interface, in a way userspace can observe?
>
> It won't up/down the interface as it doesn't exactly mimic what the
> network code does (there's more than rtnl_lock).
>
Right. Userspace wont see link down/up, but it will see carrier off/on.
But this is AFAIK acceptable for a rare situation like a tx error.
> For the same reason it's broken if it races with the transmit path: it
> can release driver resources while the transmit path uses these.
>
> Btw the points below may not matter/hurt much for a proof a concept
> but they would need to be addressed as well:
> 1) unchecked (and avoidable) extra error paths due to stmmac_release()
> 2) racy cancel_work_sync. Low probability as it is, an irq + error could
> take place right after cancel_work_sync
It was indeed only meant as a proof of concept. Nevertheless the race is not
good, since one can run into it when faking the tx error for testings purposes.
So below is a slightly improved version of the restart handling.
Its not meant as a final version either. But maybe we can use it as a starting
point.
> Lino, have you considered via-rhine.c since its "move work from irq to
> workqueue context" changes that started in
> 7ab87ff4c770eed71e3777936299292739fcd0fe [*] ?
> It's a shameless plug - originated in r8169.c - but it should be rather
> close to what the sxgbe and friends require. Thought / opinion ?
>
Not really. There are a few drivers that I use to look into if I want to know
how certain things are done correctly (e.g the sky2 or the intel drivers) because
I think they are well implemented.
But you seem to have put some thoughts into various race condition problems
in the via-rhine driver and I can image that sxgbe and stmmac still have some
of these issues, too.
> [*] Including fixes/changes in:
> - 3a5a883a8a663b930908cae4abe5ec913b9b2fd2
Ok, the issues you fixed here are concerning the tx_curr and tx_dirty
pointers. For now this is not needed in stmmac and sxgbe since the
tx completion handlers in both drivers are not lock-free like in
the via-rhine.c but are synchronized with xmit by means of the xmit_lock.
> - e1efa87241272104d6a12c8b9fcdc4f62634d447
Yep, a sync of the dma descriptors before the hardware gets ownership of the tx tail
idx is missing in the stmmac, too.
> - 810f19bcb862f8889b27e0c9d9eceac9593925dd
> - e45af497950a89459a0c4b13ffd91e1729fffef4
> - a926592f5e4e900f3fa903298c4619a131e60963
I think we should use netif_tx_disable() instead of netif_stop_queue(), too, in
case of restart to avoid a possible schedule of the xmit function while we restart.
So this is also part of the new patch.
Again the patch is only compile tested.
Regards,
Lino
---
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 +
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 95 +++++++++++++++--------
2 files changed, 63 insertions(+), 33 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index eab04ae..9c240d7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -131,6 +131,7 @@ struct stmmac_priv {
u32 rx_tail_addr;
u32 tx_tail_addr;
u32 mss;
+ struct work_struct tx_err_work;
#ifdef CONFIG_DEBUG_FS
struct dentry *dbgfs_dir;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 3e40578..5762750 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1403,37 +1403,6 @@ static inline void stmmac_disable_dma_irq(struct stmmac_priv *priv)
}
/**
- * stmmac_tx_err - to manage the tx error
- * @priv: driver private structure
- * Description: it cleans the descriptors and restarts the transmission
- * in case of transmission errors.
- */
-static void stmmac_tx_err(struct stmmac_priv *priv)
-{
- int i;
- netif_stop_queue(priv->dev);
-
- priv->hw->dma->stop_tx(priv->ioaddr);
- dma_free_tx_skbufs(priv);
- for (i = 0; i < DMA_TX_SIZE; i++)
- if (priv->extend_desc)
- priv->hw->desc->init_tx_desc(&priv->dma_etx[i].basic,
- priv->mode,
- (i == DMA_TX_SIZE - 1));
- else
- priv->hw->desc->init_tx_desc(&priv->dma_tx[i],
- priv->mode,
- (i == DMA_TX_SIZE - 1));
- priv->dirty_tx = 0;
- priv->cur_tx = 0;
- netdev_reset_queue(priv->dev);
- priv->hw->dma->start_tx(priv->ioaddr);
-
- priv->dev->stats.tx_errors++;
- netif_wake_queue(priv->dev);
-}
-
-/**
* stmmac_dma_interrupt - DMA ISR
* @priv: driver private structure
* Description: this is the DMA ISR. It is called by the main ISR.
@@ -1466,7 +1435,7 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
priv->xstats.threshold = tc;
}
} else if (unlikely(status == tx_hard_error))
- stmmac_tx_err(priv);
+ schedule_work(&priv->tx_err_work);
}
/**
@@ -1902,6 +1871,7 @@ static int stmmac_release(struct net_device *dev)
if (priv->lpi_irq > 0)
free_irq(priv->lpi_irq, dev);
+ cancel_work_sync(&priv->tx_err_work);
/* Stop TX/RX DMA and clear the descriptors */
priv->hw->dma->stop_tx(priv->ioaddr);
priv->hw->dma->stop_rx(priv->ioaddr);
@@ -1920,9 +1890,67 @@ static int stmmac_release(struct net_device *dev)
stmmac_release_ptp(priv);
+
return 0;
}
+static void stmmac_shutdown(struct net_device *dev)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ /* make sure xmit is not scheduled any more */
+ netif_tx_disable(dev);
+
+ if (priv->eee_enabled)
+ del_timer_sync(&priv->eee_ctrl_timer);
+
+ /* Stop and disconnect the PHY */
+ if (dev->phydev) {
+ phy_stop(dev->phydev);
+ phy_disconnect(dev->phydev);
+ }
+
+ napi_disable(&priv->napi);
+
+ del_timer_sync(&priv->txtimer);
+
+ /* Free the IRQ lines */
+ free_irq(dev->irq, dev);
+ if (priv->wol_irq != dev->irq)
+ free_irq(priv->wol_irq, dev);
+ if (priv->lpi_irq > 0)
+ free_irq(priv->lpi_irq, dev);
+
+ /* Stop TX/RX DMA and clear the descriptors */
+ priv->hw->dma->stop_tx(priv->ioaddr);
+ priv->hw->dma->stop_rx(priv->ioaddr);
+
+ /* Release and free the Rx/Tx resources */
+ free_dma_desc_resources(priv);
+
+ /* Disable the MAC Rx/Tx */
+ stmmac_set_mac(priv->ioaddr, false);
+
+ netif_carrier_off(dev);
+
+#ifdef CONFIG_DEBUG_FS
+ stmmac_exit_fs(dev);
+#endif
+
+ stmmac_release_ptp(priv);
+}
+
+static void stmmac_tx_err_work(struct work_struct *work)
+{
+ struct stmmac_priv *priv = container_of(work, struct stmmac_priv,
+ tx_err_work);
+ /* restart netdev */
+ rtnl_lock();
+ stmmac_shutdown(priv->dev);
+ stmmac_open(priv->dev);
+ rtnl_unlock();
+}
+
/**
* stmmac_tso_allocator - close entry point of the driver
* @priv: driver private structure
@@ -2688,7 +2716,7 @@ static void stmmac_tx_timeout(struct net_device *dev)
struct stmmac_priv *priv = netdev_priv(dev);
/* Clear Tx resources and restart transmitting again */
- stmmac_tx_err(priv);
+ schedule_work(&priv->tx_err_work);
}
/**
@@ -3338,6 +3366,7 @@ int stmmac_dvr_probe(struct device *device,
netif_napi_add(ndev, &priv->napi, stmmac_poll, 64);
spin_lock_init(&priv->lock);
+ INIT_WORK(&priv->tx_err_work, stmmac_tx_err_work);
ret = register_netdev(ndev);
if (ret) {
--
1.9.1
next prev parent reply other threads:[~2016-12-18 16:15 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-12-07 20:05 Remove private locks to avoid possible deadlock Lino Sanfilippo
2016-12-07 20:05 ` [PATCH 1/2] net: ethernet: sxgbe: remove private tx queue lock Lino Sanfilippo
2016-12-07 23:15 ` Francois Romieu
2016-12-08 20:32 ` Lino Sanfilippo
2016-12-08 21:54 ` Pavel Machek
2016-12-08 22:12 ` Lino Sanfilippo
2016-12-08 22:18 ` Pavel Machek
2016-12-08 22:45 ` Lino Sanfilippo
2016-12-08 23:19 ` Francois Romieu
2016-12-09 11:21 ` Pavel Machek
2016-12-10 2:25 ` Lino Sanfilippo
2016-12-11 20:11 ` Pavel Machek
2016-12-15 19:27 ` Lino Sanfilippo
2016-12-15 21:03 ` Pavel Machek
2016-12-15 21:32 ` Lino Sanfilippo
2016-12-15 22:33 ` Lino Sanfilippo
2016-12-17 17:31 ` Pavel Machek
2016-12-18 0:15 ` Francois Romieu
2016-12-18 16:15 ` Lino Sanfilippo [this message]
2016-12-18 17:23 ` Pavel Machek
2016-12-18 18:30 ` Pavel Machek
2016-12-19 22:49 ` Lino Sanfilippo
2016-12-18 20:16 ` Pavel Machek
2016-12-19 10:02 ` Pavel Machek
2016-12-20 0:05 ` Francois Romieu
2016-12-07 20:05 ` [PATCH 2/2] net: ethernet: stmmac: " Lino Sanfilippo
2016-12-07 20:55 ` Pavel Machek
2016-12-07 20:59 ` Pavel Machek
2016-12-07 21:37 ` Pavel Machek
2016-12-07 21:43 ` Lino Sanfilippo
2016-12-07 22:34 ` Lino Sanfilippo
2016-12-07 23:21 ` Pavel Machek
2016-12-07 23:41 ` David Miller
2016-12-08 14:08 ` Pavel Machek
2016-12-08 15:26 ` David Miller
2016-12-08 15:46 ` Pavel Machek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=a2cbcfcd-f377-565c-a21c-3daa3abce519@gmx.de \
--to=linosanfilippo@gmx.de \
--cc=alexandre.torgue@st.com \
--cc=bh74.an@samsung.com \
--cc=davem@davemloft.net \
--cc=ks.giri@samsung.com \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pavel@ucw.cz \
--cc=peppe.cavallaro@st.com \
--cc=romieu@fr.zoreil.com \
--cc=vipul.pandya@samsung.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).