summaryrefslogtreecommitdiffstats
path: root/drivers/staging/hv/netvsc_drv.c
diff options
context:
space:
mode:
authorStephen Hemminger2010-03-10 02:42:17 +0100
committerGreg Kroah-Hartman2010-05-11 20:35:34 +0200
commit9495c282baf53ec7bfffcb9dd9f40cb10d4240e0 (patch)
treea33b856ca0d76a94f47169f7f9b454ce006008ae /drivers/staging/hv/netvsc_drv.c
parentStaging: hv: use network device stats (diff)
downloadkernel-qcow2-linux-9495c282baf53ec7bfffcb9dd9f40cb10d4240e0.tar.gz
kernel-qcow2-linux-9495c282baf53ec7bfffcb9dd9f40cb10d4240e0.tar.xz
kernel-qcow2-linux-9495c282baf53ec7bfffcb9dd9f40cb10d4240e0.zip
Staging: hv: handle skb allocation failure
Some fixes to receive handling: * Dieing with assertion failure when running out of memory is not ok * Use newer alloc function to get aligned skb * Dropped statistic is supposed to be incremented only by driver it was responsible for the drop. Compile tested only. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Cc: Hank Janssen <hjanssen@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/hv/netvsc_drv.c')
-rw-r--r--drivers/staging/hv/netvsc_drv.c32
1 files changed, 12 insertions, 20 deletions
diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c
index e87a7c205d85..51a56e2b43c1 100644
--- a/drivers/staging/hv/netvsc_drv.c
+++ b/drivers/staging/hv/netvsc_drv.c
@@ -294,7 +294,6 @@ static int netvsc_recv_callback(struct hv_device *device_obj,
struct net_device_context *net_device_ctx;
struct sk_buff *skb;
void *data;
- int ret;
int i;
unsigned long flags;
@@ -308,12 +307,12 @@ static int netvsc_recv_callback(struct hv_device *device_obj,
net_device_ctx = netdev_priv(net);
- /* Allocate a skb - TODO preallocate this */
- /* Pad 2-bytes to align IP header to 16 bytes */
- skb = dev_alloc_skb(packet->TotalDataBufferLength + 2);
- ASSERT(skb);
- skb_reserve(skb, 2);
- skb->dev = net;
+ /* Allocate a skb - TODO direct I/O to pages? */
+ skb = netdev_alloc_skb_ip_align(net, packet->TotalDataBufferLength);
+ if (unlikely(!skb)) {
+ ++net->stats.rx_dropped;
+ return 0;
+ }
/* for kmap_atomic */
local_irq_save(flags);
@@ -338,25 +337,18 @@ static int netvsc_recv_callback(struct hv_device *device_obj,
local_irq_restore(flags);
skb->protocol = eth_type_trans(skb, net);
-
skb->ip_summed = CHECKSUM_NONE;
+ net->stats.rx_packets++;
+ net->stats.rx_bytes += skb->len;
+
/*
* Pass the skb back up. Network stack will deallocate the skb when it
- * is done
+ * is done.
+ * TODO - use NAPI?
*/
- ret = netif_rx(skb);
-
- switch (ret) {
- case NET_RX_DROP:
- net->stats.rx_dropped++;
- break;
- default:
- net->stats.rx_packets++;
- net->stats.rx_bytes += skb->len;
- break;
+ netif_rx(skb);
- }
DPRINT_DBG(NETVSC_DRV, "# of recvs %lu total size %lu",
net->stats.rx_packets, net->stats.rx_bytes);