diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-07-07 19:56:00 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-07-07 19:56:00 -0700 |
commit | 2aa72f612144a0a7d4b0b22ae7c122692ac6a013 (patch) | |
tree | 8af2d2ac975887a04b4e4109de3d785f7046979b /drivers/net/virtio_net.c | |
parent | 78178c7d6e127fff6dba027315fd6914304b05cf (diff) | |
parent | 33b665eeeb85956ccbdf31c4c31a4e2a31133c44 (diff) | |
download | talos-op-linux-2aa72f612144a0a7d4b0b22ae7c122692ac6a013.tar.gz talos-op-linux-2aa72f612144a0a7d4b0b22ae7c122692ac6a013.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (35 commits)
NET: SB1250: Initialize .owner
vxge: show startup message with KERN_INFO
ll_temac: Fix missing iounmaps
bridge: Clear IPCB before possible entry into IP stack
bridge br_multicast: BUG: unable to handle kernel NULL pointer dereference
net: Fix definition of netif_vdbg() when VERBOSE_DEBUG is defined
net/ne: fix memory leak in ne_drv_probe()
xfrm: fix xfrm by MARK logic
virtio_net: fix oom handling on tx
virtio_net: do not reschedule rx refill forever
s2io: resolve statistics issues
linux/net.h: fix kernel-doc warnings
net: decreasing real_num_tx_queues needs to flush qdisc
sched: qdisc_reset_all_tx is calling qdisc_reset without qdisc_lock
qlge: fix a eeh handler to not add a pending timer
qlge: Replacing add_timer() to mod_timer()
usbnet: Set parent device early for netdev_printk()
net: Revert "rndis_host: Poll status channel before control channel"
netfilter: ip6t_REJECT: fix a dst leak in ipv6 REJECT
drivers: bluetooth: bluecard_cs.c: Fixed include error, changed to linux/io.h
...
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r-- | drivers/net/virtio_net.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 1edb7a61983c..bb6b67f6b0cc 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -415,7 +415,7 @@ static int add_recvbuf_mergeable(struct virtnet_info *vi, gfp_t gfp) static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp) { int err; - bool oom = false; + bool oom; do { if (vi->mergeable_rx_bufs) @@ -425,10 +425,9 @@ static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp) else err = add_recvbuf_small(vi, gfp); - if (err < 0) { - oom = true; + oom = err == -ENOMEM; + if (err < 0) break; - } ++vi->num; } while (err > 0); if (unlikely(vi->num > vi->max)) @@ -563,7 +562,6 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) struct virtnet_info *vi = netdev_priv(dev); int capacity; -again: /* Free up any pending old buffers before queueing new ones. */ free_old_xmit_skbs(vi); @@ -572,14 +570,20 @@ again: /* This can happen with OOM and indirect buffers. */ if (unlikely(capacity < 0)) { - netif_stop_queue(dev); - dev_warn(&dev->dev, "Unexpected full queue\n"); - if (unlikely(!virtqueue_enable_cb(vi->svq))) { - virtqueue_disable_cb(vi->svq); - netif_start_queue(dev); - goto again; + if (net_ratelimit()) { + if (likely(capacity == -ENOMEM)) { + dev_warn(&dev->dev, + "TX queue failure: out of memory\n"); + } else { + dev->stats.tx_fifo_errors++; + dev_warn(&dev->dev, + "Unexpected TX queue failure: %d\n", + capacity); + } } - return NETDEV_TX_BUSY; + dev->stats.tx_dropped++; + kfree_skb(skb); + return NETDEV_TX_OK; } virtqueue_kick(vi->svq); |