diff options
author | Dhananjay Phadke <dhananjay@netxen.com> | 2009-07-17 15:27:07 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-07-20 08:23:31 -0700 |
commit | b2af9cb06d4de1b507ec0fd779ec2ecedee1480a (patch) | |
tree | 15967d7eaee2636e6c29d15d96dd57e99c0a6ee9 /drivers/net/netxen/netxen_nic_hw.c | |
parent | cf981ffb31e8f41f4899a56560f81322f94f22d1 (diff) |
netxen: fix deadlock on dev close
netxen: fix deadlock on dev close
The tx ring accounting fix in commit cb2107be43d2fc5eadec58b92b
("netxen: fix tx ring accounting") introduced intermittent
deadlock when inteface is going down.
This was possibly combined effect of speculative tx pause,
calling netif_tx_lock instead of queue lock and unclean
synchronization with napi which could end up unmasking
interrupt.
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/netxen/netxen_nic_hw.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index ce3b89d2cbb..b9123d445c9 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -461,13 +461,14 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, i = 0; tx_ring = adapter->tx_ring; - netif_tx_lock_bh(adapter->netdev); + __netif_tx_lock_bh(tx_ring->txq); producer = tx_ring->producer; consumer = tx_ring->sw_consumer; - if (nr_desc >= find_diff_among(producer, consumer, tx_ring->num_desc)) { - netif_tx_unlock_bh(adapter->netdev); + if (nr_desc >= netxen_tx_avail(tx_ring)) { + netif_tx_stop_queue(tx_ring->txq); + __netif_tx_unlock_bh(tx_ring->txq); return -EBUSY; } @@ -490,7 +491,7 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, netxen_nic_update_cmd_producer(adapter, tx_ring); - netif_tx_unlock_bh(adapter->netdev); + __netif_tx_unlock_bh(tx_ring->txq); return 0; } |