Commit 72259225 authored by Amir Vadai's avatar Amir Vadai Committed by David S. Miller

net/mlx4_en: Fix a race when closing TX queue

There is a possible race where the TX completion handler can clean the
entire TX queue between the decision that the queue is full and actually
closing it. To avoid this situation, check again if the queue is really
full, if not, reopen the transmit and continue with sending the packet.

CC: Eric Dumazet <edumazet@google.com>
Signed-off-by: default avatarYevgeny Petrilin <yevgenyp@mellanox.com>
Signed-off-by: default avatarEugenia Emantayev <eugenia@mellanox.com>
Signed-off-by: default avatarAmir Vadai <amirv@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f356fcbe
...@@ -588,8 +588,22 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -588,8 +588,22 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
netif_tx_stop_queue(ring->tx_queue); netif_tx_stop_queue(ring->tx_queue);
priv->port_stats.queue_stopped++; priv->port_stats.queue_stopped++;
/* If queue was emptied after the if, and before the
* stop_queue - need to wake the queue, or else it will remain
* stopped forever.
* Need a memory barrier to make sure ring->cons was not
* updated before queue was stopped.
*/
wmb();
if (unlikely(((int)(ring->prod - ring->cons)) <=
ring->size - HEADROOM - MAX_DESC_TXBBS)) {
netif_tx_wake_queue(ring->tx_queue);
priv->port_stats.wake_queue++;
} else {
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
} }
}
/* Track current inflight packets for performance analysis */ /* Track current inflight packets for performance analysis */
AVG_PERF_COUNTER(priv->pstats.inflight_avg, AVG_PERF_COUNTER(priv->pstats.inflight_avg,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment