Skip to content

Commit

Permalink
netxen: fix race in tx ring acccess
Browse files Browse the repository at this point in the history
Fix the distance check between tx ring producer and consumer that
could lead to tx ring wrap around.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Dhananjay Phadke authored and David S. Miller committed May 6, 2009
1 parent 78a658d commit 2252786
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 7 deletions.
4 changes: 2 additions & 2 deletions drivers/net/netxen/netxen_nic_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter,
producer = tx_ring->producer;
consumer = tx_ring->sw_consumer;

if (nr_desc > find_diff_among(producer, consumer, tx_ring->num_desc)) {
if (nr_desc >= find_diff_among(producer, consumer, tx_ring->num_desc)) {
netif_tx_unlock_bh(adapter->netdev);
return -EBUSY;
}
Expand Down Expand Up @@ -752,7 +752,7 @@ int netxen_linkevent_request(struct netxen_adapter *adapter, int enable)

word = NX_NIC_H2C_OPCODE_GET_LINKEVENT | ((u64)adapter->portnum << 16);
req.req_hdr = cpu_to_le64(word);
req.words[0] = cpu_to_le64(enable);
req.words[0] = cpu_to_le64(enable | (enable << 8));

rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
if (rv != 0) {
Expand Down
8 changes: 4 additions & 4 deletions drivers/net/netxen/netxen_nic_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -1319,10 +1319,11 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
break;
}

if (count) {
tx_ring->sw_consumer = sw_consumer;
tx_ring->sw_consumer = sw_consumer;

if (count && netif_running(netdev)) {
smp_mb();
if (netif_queue_stopped(netdev) && netif_running(netdev)) {
if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) {
netif_tx_lock(netdev);
netif_wake_queue(netdev);
smp_mb();
Expand Down Expand Up @@ -1450,7 +1451,6 @@ netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
rds_ring->producer = producer;
NXWR32(adapter, rds_ring->crb_rcv_producer,
(producer - 1) & (rds_ring->num_desc - 1));
wmb();
}
spin_unlock(&rds_ring->lock);
}
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/netxen/netxen_nic_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,7 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
{
netif_carrier_off(netdev);
netif_stop_queue(netdev);
smp_mb();
netxen_napi_disable(adapter);

if (adapter->stop_port)
Expand Down Expand Up @@ -1340,7 +1341,7 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
producer = tx_ring->producer;
smp_mb();
consumer = tx_ring->sw_consumer;
if ((no_of_desc+2) > find_diff_among(producer, consumer, num_txd)) {
if ((no_of_desc+2) >= find_diff_among(producer, consumer, num_txd)) {
netif_stop_queue(netdev);
smp_mb();
return NETDEV_TX_BUSY;
Expand Down

0 comments on commit 2252786

Please sign in to comment.