aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@vyatta.com>2010-03-09 20:42:17 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-11 14:35:34 -0400
commit9495c282baf53ec7bfffcb9dd9f40cb10d4240e0 (patch)
treea33b856ca0d76a94f47169f7f9b454ce006008ae /drivers
parentb852fdcefc782b6751f96a8ea09471efd844b6bf (diff)
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')
-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 e87a7c205d8..51a56e2b43c 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,
294 struct net_device_context *net_device_ctx; 294 struct net_device_context *net_device_ctx;
295 struct sk_buff *skb; 295 struct sk_buff *skb;
296 void *data; 296 void *data;
297 int ret;
298 int i; 297 int i;
299 unsigned long flags; 298 unsigned long flags;
300 299
@@ -308,12 +307,12 @@ static int netvsc_recv_callback(struct hv_device *device_obj,
308 307
309 net_device_ctx = netdev_priv(net); 308 net_device_ctx = netdev_priv(net);
310 309
311 /* Allocate a skb - TODO preallocate this */ 310 /* Allocate a skb - TODO direct I/O to pages? */
312 /* Pad 2-bytes to align IP header to 16 bytes */ 311 skb = netdev_alloc_skb_ip_align(net, packet->TotalDataBufferLength);
313 skb = dev_alloc_skb(packet->TotalDataBufferLength + 2); 312 if (unlikely(!skb)) {
314 ASSERT(skb); 313 ++net->stats.rx_dropped;
315 skb_reserve(skb, 2); 314 return 0;
316 skb->dev = net; 315 }
317 316
318 /* for kmap_atomic */ 317 /* for kmap_atomic */
319 local_irq_save(flags); 318 local_irq_save(flags);
@@ -338,25 +337,18 @@ static int netvsc_recv_callback(struct hv_device *device_obj,
338 local_irq_restore(flags); 337 local_irq_restore(flags);
339 338
340 skb->protocol = eth_type_trans(skb, net); 339 skb->protocol = eth_type_trans(skb, net);
341
342 skb->ip_summed = CHECKSUM_NONE; 340 skb->ip_summed = CHECKSUM_NONE;
343 341
342 net->stats.rx_packets++;
343 net->stats.rx_bytes += skb->len;
344
344 /* 345 /*
345 * Pass the skb back up. Network stack will deallocate the skb when it 346 * Pass the skb back up. Network stack will deallocate the skb when it
346 * is done 347 * is done.
348 * TODO - use NAPI?
347 */ 349 */
348 ret = netif_rx(skb); 350 netif_rx(skb);
349
350 switch (ret) {
351 case NET_RX_DROP:
352 net->stats.rx_dropped++;
353 break;
354 default:
355 net->stats.rx_packets++;
356 net->stats.rx_bytes += skb->len;
357 break;
358 351
359 }
360 DPRINT_DBG(NETVSC_DRV, "# of recvs %lu total size %lu", 352 DPRINT_DBG(NETVSC_DRV, "# of recvs %lu total size %lu",
361 net->stats.rx_packets, net->stats.rx_bytes); 353 net->stats.rx_packets, net->stats.rx_bytes);
362 354