Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[safe/jmp/linux-2.6] / drivers / net / virtio_net.c
index effe8c6..b9e002f 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/ethtool.h>
 #include <linux/module.h>
 #include <linux/virtio.h>
-#include <linux/virtio_ids.h>
 #include <linux/virtio_net.h>
 #include <linux/scatterlist.h>
 #include <linux/if_vlan.h>
@@ -280,7 +279,7 @@ static bool try_fill_recv_maxbufs(struct virtnet_info *vi, gfp_t gfp)
        bool oom = false;
 
        sg_init_table(sg, 2+MAX_SKB_FRAGS);
-       for (;;) {
+       do {
                struct skb_vnet_hdr *hdr;
 
                skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN + NET_IP_ALIGN);
@@ -323,7 +322,7 @@ static bool try_fill_recv_maxbufs(struct virtnet_info *vi, gfp_t gfp)
                        break;
                }
                vi->num++;
-       }
+       } while (err >= num);
        if (unlikely(vi->num > vi->max))
                vi->max = vi->num;
        vi->rvq->vq_ops->kick(vi->rvq);
@@ -341,7 +340,7 @@ static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp)
        if (!vi->mergeable_rx_bufs)
                return try_fill_recv_maxbufs(vi, gfp);
 
-       for (;;) {
+       do {
                skb_frag_t *f;
 
                skb = netdev_alloc_skb(vi->dev, GOOD_COPY_LEN + NET_IP_ALIGN);
@@ -375,7 +374,7 @@ static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp)
                        break;
                }
                vi->num++;
-       }
+       } while (err > 0);
        if (unlikely(vi->num > vi->max))
                vi->max = vi->num;
        vi->rvq->vq_ops->kick(vi->rvq);
@@ -454,7 +453,7 @@ static unsigned int free_old_xmit_skbs(struct virtnet_info *vi)
                vi->dev->stats.tx_bytes += skb->len;
                vi->dev->stats.tx_packets++;
                tot_sgs += skb_vnet_hdr(skb)->num_sg;
-               kfree_skb(skb);
+               dev_kfree_skb_any(skb);
        }
        return tot_sgs;
 }
@@ -517,8 +516,7 @@ again:
        /* Free up any pending old buffers before queueing new ones. */
        free_old_xmit_skbs(vi);
 
-       /* Put new one in send queue and do transmit */
-       __skb_queue_head(&vi->send, skb);
+       /* Try to transmit */
        capacity = xmit_skb(vi, skb);
 
        /* This can happen with OOM and indirect buffers. */
@@ -532,8 +530,17 @@ again:
                }
                return NETDEV_TX_BUSY;
        }
-
        vi->svq->vq_ops->kick(vi->svq);
+
+       /*
+        * Put new one in send queue.  You'd expect we'd need this before
+        * xmit_skb calls add_buf(), since the callback can be triggered
+        * immediately after that.  But since the callback just triggers
+        * another call back here, normal network xmit locking prevents the
+        * race.
+        */
+       __skb_queue_head(&vi->send, skb);
+
        /* Don't wait up for transmitted skbs to be freed. */
        skb_orphan(skb);
        nf_reset(skb);
@@ -948,7 +955,7 @@ free:
        return err;
 }
 
-static void virtnet_remove(struct virtio_device *vdev)
+static void __devexit virtnet_remove(struct virtio_device *vdev)
 {
        struct virtnet_info *vi = vdev->priv;
        struct sk_buff *skb;
@@ -991,7 +998,7 @@ static unsigned int features[] = {
        VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
 };
 
-static struct virtio_driver virtio_net = {
+static struct virtio_driver virtio_net_driver = {
        .feature_table = features,
        .feature_table_size = ARRAY_SIZE(features),
        .driver.name =  KBUILD_MODNAME,
@@ -1004,12 +1011,12 @@ static struct virtio_driver virtio_net = {
 
 static int __init init(void)
 {
-       return register_virtio_driver(&virtio_net);
+       return register_virtio_driver(&virtio_net_driver);
 }
 
 static void __exit fini(void)
 {
-       unregister_virtio_driver(&virtio_net);
+       unregister_virtio_driver(&virtio_net_driver);
 }
 module_init(init);
 module_exit(fini);