aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/virtio_net.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2009-09-24 11:59:19 -0400
committerRusty Russell <rusty@rustcorp.com.au>2009-09-23 20:29:19 -0400
commitb0c39dbdc204006ef3558a66716ff09797619778 (patch)
treedf0509538a4d8e559737407b5b9b8a53cbf5c719 /drivers/net/virtio_net.c
parent8958f574dbe7e41cc54df0df1accc861bb9f6be8 (diff)
virtio_net: don't free buffers in xmit ring
The virtio_net driver is complicated by the two methods of freeing old xmit buffers (in addition to freeing old ones at the start of the xmit path). The original code used a 1/10 second timer attached to xmit_free(), reset on every xmit. Before we orphaned skbs on xmit, the transmitting userspace could block with a full socket until the timer fired, the skb destructor was called, and they were re-woken. So we added the VIRTIO_F_NOTIFY_ON_EMPTY feature: supporting devices send an interrupt (even if normally suppressed) on an empty xmit ring which makes us schedule xmit_tasklet(). This was a benchmark win. Unfortunately, VIRTIO_F_NOTIFY_ON_EMPTY makes quite a lot of work: a host which is faster than the guest will fire the interrupt every xmit packet (slowing the guest down further). Attempting mitigation in the host adds overhead of userspace timers (possibly with the additional pain of signals), and risks increasing latency anyway if you get it wrong. In practice, this effect was masked by benchmarks which take advantage of GSO (with its inherent transmit batching), but it's still there. Now we orphan xmitted skbs, the pressure is off: remove both paths and no longer request VIRTIO_F_NOTIFY_ON_EMPTY. Note that the current QEMU will notify us even if we don't negotiate this feature (legal, but suboptimal); a patch is outstanding to improve that. Move the skb_orphan/nf_reset to after we've done the send and notified the other end, for a slight optimization. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Cc: Mark McLoughlin <markmc@redhat.com>
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r--drivers/net/virtio_net.c64
1 files changed, 5 insertions, 59 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 222f3d098ae4..3041e4eddb3b 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -48,16 +48,9 @@ struct virtnet_info
48 struct napi_struct napi; 48 struct napi_struct napi;
49 unsigned int status; 49 unsigned int status;
50 50
51 /* If we need to free in a timer, this is it. */
52 struct timer_list xmit_free_timer;
53
54 /* Number of input buffers, and max we've ever had. */ 51 /* Number of input buffers, and max we've ever had. */
55 unsigned int num, max; 52 unsigned int num, max;
56 53
57 /* For cleaning up after transmission. */
58 struct tasklet_struct tasklet;
59 bool free_in_tasklet;
60
61 /* I like... big packets and I cannot lie! */ 54 /* I like... big packets and I cannot lie! */
62 bool big_packets; 55 bool big_packets;
63 56
@@ -116,9 +109,6 @@ static void skb_xmit_done(struct virtqueue *svq)
116 109
117 /* We were probably waiting for more output buffers. */ 110 /* We were probably waiting for more output buffers. */
118 netif_wake_queue(vi->dev); 111 netif_wake_queue(vi->dev);
119
120 if (vi->free_in_tasklet)
121 tasklet_schedule(&vi->tasklet);
122} 112}
123 113
124static void receive_skb(struct net_device *dev, struct sk_buff *skb, 114static void receive_skb(struct net_device *dev, struct sk_buff *skb,
@@ -458,25 +448,9 @@ static void free_old_xmit_skbs(struct virtnet_info *vi)
458 } 448 }
459} 449}
460 450
461/* If the virtio transport doesn't always notify us when all in-flight packets
462 * are consumed, we fall back to using this function on a timer to free them. */
463static void xmit_free(unsigned long data)
464{
465 struct virtnet_info *vi = (void *)data;
466
467 netif_tx_lock(vi->dev);
468
469 free_old_xmit_skbs(vi);
470
471 if (!skb_queue_empty(&vi->send))
472 mod_timer(&vi->xmit_free_timer, jiffies + (HZ/10));
473
474 netif_tx_unlock(vi->dev);
475}
476
477static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) 451static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
478{ 452{
479 int num, err; 453 int num;
480 struct scatterlist sg[2+MAX_SKB_FRAGS]; 454 struct scatterlist sg[2+MAX_SKB_FRAGS];
481 struct virtio_net_hdr_mrg_rxbuf *mhdr = skb_vnet_hdr(skb); 455 struct virtio_net_hdr_mrg_rxbuf *mhdr = skb_vnet_hdr(skb);
482 struct virtio_net_hdr *hdr = skb_vnet_hdr(skb); 456 struct virtio_net_hdr *hdr = skb_vnet_hdr(skb);
@@ -522,25 +496,7 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
522 sg_set_buf(sg, hdr, sizeof(*hdr)); 496 sg_set_buf(sg, hdr, sizeof(*hdr));
523 497
524 num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; 498 num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
525 499 return vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb);
526 err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb);
527 if (err >= 0 && !vi->free_in_tasklet) {
528 /* Don't wait up for transmitted skbs to be freed. */
529 skb_orphan(skb);
530 nf_reset(skb);
531 mod_timer(&vi->xmit_free_timer, jiffies + (HZ/10));
532 }
533
534 return err;
535}
536
537static void xmit_tasklet(unsigned long data)
538{
539 struct virtnet_info *vi = (void *)data;
540
541 netif_tx_lock_bh(vi->dev);
542 free_old_xmit_skbs(vi);
543 netif_tx_unlock_bh(vi->dev);
544} 500}
545 501
546static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) 502static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -555,6 +511,9 @@ again:
555 __skb_queue_head(&vi->send, skb); 511 __skb_queue_head(&vi->send, skb);
556 if (likely(xmit_skb(vi, skb) >= 0)) { 512 if (likely(xmit_skb(vi, skb) >= 0)) {
557 vi->svq->vq_ops->kick(vi->svq); 513 vi->svq->vq_ops->kick(vi->svq);
514 /* Don't wait up for transmitted skbs to be freed. */
515 skb_orphan(skb);
516 nf_reset(skb);
558 return NETDEV_TX_OK; 517 return NETDEV_TX_OK;
559 } 518 }
560 519
@@ -903,10 +862,6 @@ static int virtnet_probe(struct virtio_device *vdev)
903 vi->pages = NULL; 862 vi->pages = NULL;
904 INIT_DELAYED_WORK(&vi->refill, refill_work); 863 INIT_DELAYED_WORK(&vi->refill, refill_work);
905 864
906 /* If they give us a callback when all buffers are done, we don't need
907 * the timer. */
908 vi->free_in_tasklet = virtio_has_feature(vdev,VIRTIO_F_NOTIFY_ON_EMPTY);
909
910 /* If we can receive ANY GSO packets, we must allocate large ones. */ 865 /* If we can receive ANY GSO packets, we must allocate large ones. */
911 if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) 866 if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4)
912 || virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) 867 || virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6)
@@ -938,11 +893,6 @@ static int virtnet_probe(struct virtio_device *vdev)
938 skb_queue_head_init(&vi->recv); 893 skb_queue_head_init(&vi->recv);
939 skb_queue_head_init(&vi->send); 894 skb_queue_head_init(&vi->send);
940 895
941 tasklet_init(&vi->tasklet, xmit_tasklet, (unsigned long)vi);
942
943 if (!vi->free_in_tasklet)
944 setup_timer(&vi->xmit_free_timer, xmit_free, (unsigned long)vi);
945
946 err = register_netdev(dev); 896 err = register_netdev(dev);
947 if (err) { 897 if (err) {
948 pr_debug("virtio_net: registering device failed\n"); 898 pr_debug("virtio_net: registering device failed\n");
@@ -983,9 +933,6 @@ static void virtnet_remove(struct virtio_device *vdev)
983 /* Stop all the virtqueues. */ 933 /* Stop all the virtqueues. */
984 vdev->config->reset(vdev); 934 vdev->config->reset(vdev);
985 935
986 if (!vi->free_in_tasklet)
987 del_timer_sync(&vi->xmit_free_timer);
988
989 /* Free our skbs in send and recv queues, if any. */ 936 /* Free our skbs in send and recv queues, if any. */
990 while ((skb = __skb_dequeue(&vi->recv)) != NULL) { 937 while ((skb = __skb_dequeue(&vi->recv)) != NULL) {
991 kfree_skb(skb); 938 kfree_skb(skb);
@@ -1019,7 +966,6 @@ static unsigned int features[] = {
1019 VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO, 966 VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO,
1020 VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ, 967 VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ,
1021 VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, 968 VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
1022 VIRTIO_F_NOTIFY_ON_EMPTY,
1023}; 969};
1024 970
1025static struct virtio_driver virtio_net = { 971static struct virtio_driver virtio_net = {