Skip to content

Commit

Permalink
net/mlx4_en: Fix a race when closing TX queue
Browse files Browse the repository at this point in the history
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: Yevgeny Petrilin <yevgenyp@mellanox.com>
Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com>
Signed-off-by: Amir Vadai <amirv@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Amir Vadai authored and David S. Miller committed Jan 28, 2013
1 parent f356fcb commit 7225922
Showing 1 changed file with 15 additions and 1 deletion.
16 changes: 15 additions & 1 deletion drivers/net/ethernet/mellanox/mlx4/en_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,21 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
netif_tx_stop_queue(ring->tx_queue);
priv->port_stats.queue_stopped++;

return NETDEV_TX_BUSY;
/* 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;
}
}

/* Track current inflight packets for performance analysis */
Expand Down

0 comments on commit 7225922

Please sign in to comment.