forcedeth: xmit lock fix
This patch fixes a potential race condition between xmit thread and xmit completion thread. The calculation of empty tx descriptors is not performed under the lock. This could cause it to set the stop flag while the completion thread finishes all tx's. This will result in the tx queue in stopped state and no one to wake it up. Signed-off-by: Ayaz Abdulla <aabdulla@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
52255bbe35
commit
001eb84bbf
|
@ -2096,14 +2096,15 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
((skb_shinfo(skb)->frags[i].size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&np->lock, flags);
|
||||
empty_slots = nv_get_empty_tx_slots(np);
|
||||
if (unlikely(empty_slots <= entries)) {
|
||||
spin_lock_irqsave(&np->lock, flags);
|
||||
netif_stop_queue(dev);
|
||||
np->tx_stop = 1;
|
||||
spin_unlock_irqrestore(&np->lock, flags);
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
spin_unlock_irqrestore(&np->lock, flags);
|
||||
|
||||
start_tx = put_tx = np->put_tx.orig;
|
||||
|
||||
|
@ -2214,14 +2215,15 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
|
|||
((skb_shinfo(skb)->frags[i].size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&np->lock, flags);
|
||||
empty_slots = nv_get_empty_tx_slots(np);
|
||||
if (unlikely(empty_slots <= entries)) {
|
||||
spin_lock_irqsave(&np->lock, flags);
|
||||
netif_stop_queue(dev);
|
||||
np->tx_stop = 1;
|
||||
spin_unlock_irqrestore(&np->lock, flags);
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
spin_unlock_irqrestore(&np->lock, flags);
|
||||
|
||||
start_tx = put_tx = np->put_tx.ex;
|
||||
start_tx_ctx = np->put_tx_ctx;
|
||||
|
|
Loading…
Reference in New Issue