Skip to content

Commit 7a4c003

Browse files
Ronak Doshidavem330
authored andcommitted
vmxnet3: avoid xmit reset due to a race in vmxnet3
The field txNumDeferred is used by the driver to keep track of the number of packets it has pushed to the emulation. The driver increments it on pushing the packet to the emulation and the emulation resets it to 0 at the end of the transmit. There is a possibility of a race either when (a) ESX is under heavy load or (b) workload inside VM is of low packet rate. This race results in xmit hangs when network coalescing is disabled. This change creates a local copy of txNumDeferred and uses it to perform ring arithmetic. Reported-by: Noriho Tanaka <[email protected]> Signed-off-by: Ronak Doshi <[email protected]> Acked-by: Shrikrishna Khare <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 78f1b04 commit 7a4c003

File tree

2 files changed

+10
-7
lines changed

2 files changed

+10
-7
lines changed

drivers/net/vmxnet3/vmxnet3_drv.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,8 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
977977
{
978978
int ret;
979979
u32 count;
980+
int num_pkts;
981+
int tx_num_deferred;
980982
unsigned long flags;
981983
struct vmxnet3_tx_ctx ctx;
982984
union Vmxnet3_GenericDesc *gdesc;
@@ -1075,12 +1077,12 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
10751077
#else
10761078
gdesc = ctx.sop_txd;
10771079
#endif
1080+
tx_num_deferred = le32_to_cpu(tq->shared->txNumDeferred);
10781081
if (ctx.mss) {
10791082
gdesc->txd.hlen = ctx.eth_ip_hdr_size + ctx.l4_hdr_size;
10801083
gdesc->txd.om = VMXNET3_OM_TSO;
10811084
gdesc->txd.msscof = ctx.mss;
1082-
le32_add_cpu(&tq->shared->txNumDeferred, (skb->len -
1083-
gdesc->txd.hlen + ctx.mss - 1) / ctx.mss);
1085+
num_pkts = (skb->len - gdesc->txd.hlen + ctx.mss - 1) / ctx.mss;
10841086
} else {
10851087
if (skb->ip_summed == CHECKSUM_PARTIAL) {
10861088
gdesc->txd.hlen = ctx.eth_ip_hdr_size;
@@ -1091,8 +1093,10 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
10911093
gdesc->txd.om = 0;
10921094
gdesc->txd.msscof = 0;
10931095
}
1094-
le32_add_cpu(&tq->shared->txNumDeferred, 1);
1096+
num_pkts = 1;
10951097
}
1098+
le32_add_cpu(&tq->shared->txNumDeferred, num_pkts);
1099+
tx_num_deferred += num_pkts;
10961100

10971101
if (skb_vlan_tag_present(skb)) {
10981102
gdesc->txd.ti = 1;
@@ -1118,8 +1122,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
11181122

11191123
spin_unlock_irqrestore(&tq->tx_lock, flags);
11201124

1121-
if (le32_to_cpu(tq->shared->txNumDeferred) >=
1122-
le32_to_cpu(tq->shared->txThreshold)) {
1125+
if (tx_num_deferred >= le32_to_cpu(tq->shared->txThreshold)) {
11231126
tq->shared->txNumDeferred = 0;
11241127
VMXNET3_WRITE_BAR0_REG(adapter,
11251128
VMXNET3_REG_TXPROD + tq->qid * 8,

drivers/net/vmxnet3/vmxnet3_int.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,10 @@
6969
/*
7070
* Version numbers
7171
*/
72-
#define VMXNET3_DRIVER_VERSION_STRING "1.4.11.0-k"
72+
#define VMXNET3_DRIVER_VERSION_STRING "1.4.12.0-k"
7373

7474
/* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
75-
#define VMXNET3_DRIVER_VERSION_NUM 0x01040b00
75+
#define VMXNET3_DRIVER_VERSION_NUM 0x01040c00
7676

7777
#if defined(CONFIG_PCI_MSI)
7878
/* RSS only makes sense if MSI-X is supported. */

0 commit comments

Comments
 (0)