From b203262de63c56393d09e254242b57c002d8619d Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Thu, 16 Feb 2012 01:48:56 +0000 Subject: vmxnet3: cap copy length at size of skb to prevent dropped frames on tx I was recently shown that vmxnet3 devices on transmit, will drop very small udp frames consistently. This is due to a regression introduced by commit 39d4a96fd7d2926e46151adbd18b810aeeea8ec0. This commit attempts to introduce an optimization to the tx path, indicating that the underlying hardware behaves optimally when at least 54 bytes of header data are available for direct access. This causes problems however, if the entire frame is less than 54 bytes long. The subsequent pskb_may_pull in vmxnet3_parse_and_copy_hdr fails, causing an error return code, which leads to vmxnet3_tq_xmit dropping the frame. Fix it by placing a cap on the copy length. For frames longer than 54 bytes, we do the pull as we normally would. If the frame is shorter than that, copy the whole frame, but no more. This ensures that we still get the optimization for qualifying frames, but don't do any damange for frames that are too short. Also, since I'm unable to do this, it wuold be great if vmware could follow up this patch with some additional code commentary as to why 54 bytes is an optimal pull length for a virtual NIC driver. The comment that introduced this was vague on that. Thanks! Signed-off-by: Neil Horman Reported-by: Max Matveev CC: Max Matveev CC: "David S. Miller" CC: Shreyas Bhatewara CC: "VMware, Inc." Signed-off-by: Shreyas N Bhatewara Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/vmxnet3/vmxnet3_drv.c') diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index de7fc345148..3dcd3857a36 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -843,8 +843,8 @@ vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, /* for simplicity, don't copy L4 headers */ ctx->l4_hdr_size = 0; } - ctx->copy_size = ctx->eth_ip_hdr_size + - ctx->l4_hdr_size; + ctx->copy_size = min(ctx->eth_ip_hdr_size + + ctx->l4_hdr_size, skb->len); } else { ctx->eth_ip_hdr_size = 0; ctx->l4_hdr_size = 0; -- cgit v1.2.3-70-g09d2 From efead8710aad9e384730ecf25eae0287878840d7 Mon Sep 17 00:00:00 2001 From: Shreyas Bhatewara Date: Tue, 28 Feb 2012 22:17:38 +0000 Subject: vmxnet3: Fix transport header size Fix transport header size Fix the transpoert header size for UDP packets. Signed-off-by: Shreyas N Bhatewara Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 7 +------ drivers/net/vmxnet3/vmxnet3_int.h | 4 ++-- 2 files changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers/net/vmxnet3/vmxnet3_drv.c') diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 3dcd3857a36..756c0f5565a 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -830,13 +830,8 @@ vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, ctx->l4_hdr_size = ((struct tcphdr *) skb_transport_header(skb))->doff * 4; else if (iph->protocol == IPPROTO_UDP) - /* - * Use tcp header size so that bytes to - * be copied are more than required by - * the device. - */ ctx->l4_hdr_size = - sizeof(struct tcphdr); + sizeof(struct udphdr); else ctx->l4_hdr_size = 0; } else { diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index ed54797db19..fc46a81ad53 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h @@ -70,10 +70,10 @@ /* * Version numbers */ -#define VMXNET3_DRIVER_VERSION_STRING "1.1.18.0-k" +#define VMXNET3_DRIVER_VERSION_STRING "1.1.29.0-k" /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ -#define VMXNET3_DRIVER_VERSION_NUM 0x01011200 +#define VMXNET3_DRIVER_VERSION_NUM 0x01011D00 #if defined(CONFIG_PCI_MSI) /* RSS only makes sense if MSI-X is supported. */ -- cgit v1.2.3-70-g09d2