diff options
author | Fabrice Gasnier <fabrice.gasnier@st.com> | 2014-11-04 11:08:05 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-11-05 16:22:56 -0500 |
commit | 16ee817e4365cdfe665ae8d6f6bc8f09befa1272 (patch) | |
tree | 32e8e721051138198ae714cdcbcb3cacc6bbe444 /drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |
parent | b994ca6b67ade73c2d69c00a449ad7006cd4546e (diff) |
stmmac: fix stmmac_tx_avail should be called with TX locked
stmmac_tx_avail() may lie if used unprotected. It's using cur_tx
and dirty_tx index. These index may be already in use by tx_clean
when entering xmit routine. So, this should be called locked.
This can cause transmit queue to be stuck, with following message:
NETDEV WATCHDOG: eth0 (stmmaceth): transmit queue 0 timed out
Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
Acked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/stmmac_main.c')
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 6f77a46c7e2c..bcd8a3414722 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
@@ -1894,7 +1894,10 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1894 | unsigned int nopaged_len = skb_headlen(skb); | 1894 | unsigned int nopaged_len = skb_headlen(skb); |
1895 | unsigned int enh_desc = priv->plat->enh_desc; | 1895 | unsigned int enh_desc = priv->plat->enh_desc; |
1896 | 1896 | ||
1897 | spin_lock(&priv->tx_lock); | ||
1898 | |||
1897 | if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) { | 1899 | if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) { |
1900 | spin_unlock(&priv->tx_lock); | ||
1898 | if (!netif_queue_stopped(dev)) { | 1901 | if (!netif_queue_stopped(dev)) { |
1899 | netif_stop_queue(dev); | 1902 | netif_stop_queue(dev); |
1900 | /* This is a hard error, log it. */ | 1903 | /* This is a hard error, log it. */ |
@@ -1903,8 +1906,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1903 | return NETDEV_TX_BUSY; | 1906 | return NETDEV_TX_BUSY; |
1904 | } | 1907 | } |
1905 | 1908 | ||
1906 | spin_lock(&priv->tx_lock); | ||
1907 | |||
1908 | if (priv->tx_path_in_lpi_mode) | 1909 | if (priv->tx_path_in_lpi_mode) |
1909 | stmmac_disable_eee_mode(priv); | 1910 | stmmac_disable_eee_mode(priv); |
1910 | 1911 | ||