diff options
author | Stephen Hemminger <shemminger@vyatta.com> | 2010-03-09 20:42:17 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-05-11 14:35:34 -0400 |
commit | 9495c282baf53ec7bfffcb9dd9f40cb10d4240e0 (patch) | |
tree | a33b856ca0d76a94f47169f7f9b454ce006008ae /drivers | |
parent | b852fdcefc782b6751f96a8ea09471efd844b6bf (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.c | 32 |
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 | ||