vmxnet3_reset_work() expects tx queues to be stopped (via
vmxnet3_quiesce_dev -> netif_tx_disable). However, this races with the
netif_wake_queue() call in netif_tx_timeout() such that the driver's
start_xmit routine may be called unexpectedly, triggering one of the BUG_ON
in vmxnet3_map_pkt with a stack trace like this:
RIP: 0010:[] vmxnet3_map_pkt+0x3ac/0x4c0 [vmxnet3]
[] vmxnet3_tq_xmit+0x210/0x4e0 [vmxnet3]
[] dev_hard_start_xmit+0x2e4/0x4c0
[] sch_direct_xmit+0x17e/0x1e0
[] __qdisc_run+0xd7/0x130
[] net_tx_action+0x10a/0x200
[] __do_softirq+0x11f/0x260
[] call_softirq+0x1c/0x30
[] do_softirq+0x65/0xa0
[] local_bh_enable_ip+0x99/0xa0
[] destroy_conntrack+0x96/0x110 [nf_conntrack]
[] nf_conntrack_destroy+0x12/0x20
[] skb_release_head_state+0xb5/0xf0
[] skb_release_all+0x9/0x20
[] __kfree_skb+0x9/0x90
[] vmxnet3_quiesce_dev+0x209/0x340 [vmxnet3]
[] vmxnet3_reset_work+0x6a/0xa0 [vmxnet3]
[] process_one_work+0x16c/0x350
[] worker_thread+0x17a/0x410
[] kthread+0x96/0xa0
[] kernel_thread_helper+0x4/0x10
Signed-off-by: Benjamin Poirier
---
drivers/net/vmxnet3/vmxnet3_drv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c
b/drivers/net/vmxnet3/vmxnet3_drv.c
index 4244b9d..515f7aa 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -3186,7 +3186,6 @@ vmxnet3_tx_timeout(struct net_device *netdev)
netdev_err(adapter->netdev, "tx hang\n");
schedule_work(&adapter->work);
- netif_wake_queue(adapter->netdev);
}
@@ -3213,6 +3212,7 @@ vmxnet3_reset_work(struct work_struct *data)
}
rtnl_unlock();
+ netif_wake_queue(adapter->netdev);
clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);
}
--
2.9.3