aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/virtio_net.c
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2012-10-16 09:26:14 -0400
committerRusty Russell <rusty@rustcorp.com.au>2012-12-17 23:50:32 -0500
commit6ee57bcc1e61d39c0579438055bc84087210f9b6 (patch)
tree2cae790fe378aa4be4419e40ae13f2a4e4b4d8c5 /drivers/net/virtio_net.c
parent06ca287dbac9cc19d04ac2901b8c4882c03795ff (diff)
virtio-net: correct capacity math on ring full
Capacity math on ring full is wrong: we are looking at num_sg but that might be optimistic because of indirect buffer use. The implementation also penalizes fast path with extra memory accesses for the benefit of ring full condition handling which is slow path. It's easy to query ring capacity so let's do just that. This change also makes it easier to move vnet header for tx around as follow-up patch does. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Acked-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r--drivers/net/virtio_net.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index cbf8b0625352..3db65867895b 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -557,10 +557,10 @@ again:
557 return received; 557 return received;
558} 558}
559 559
560static unsigned int free_old_xmit_skbs(struct virtnet_info *vi) 560static void free_old_xmit_skbs(struct virtnet_info *vi)
561{ 561{
562 struct sk_buff *skb; 562 struct sk_buff *skb;
563 unsigned int len, tot_sgs = 0; 563 unsigned int len;
564 struct virtnet_stats *stats = this_cpu_ptr(vi->stats); 564 struct virtnet_stats *stats = this_cpu_ptr(vi->stats);
565 565
566 while ((skb = virtqueue_get_buf(vi->svq, &len)) != NULL) { 566 while ((skb = virtqueue_get_buf(vi->svq, &len)) != NULL) {
@@ -571,10 +571,8 @@ static unsigned int free_old_xmit_skbs(struct virtnet_info *vi)
571 stats->tx_packets++; 571 stats->tx_packets++;
572 u64_stats_update_end(&stats->tx_syncp); 572 u64_stats_update_end(&stats->tx_syncp);
573 573
574 tot_sgs += skb_vnet_hdr(skb)->num_sg;
575 dev_kfree_skb_any(skb); 574 dev_kfree_skb_any(skb);
576 } 575 }
577 return tot_sgs;
578} 576}
579 577
580static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) 578static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
@@ -664,7 +662,8 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
664 netif_stop_queue(dev); 662 netif_stop_queue(dev);
665 if (unlikely(!virtqueue_enable_cb_delayed(vi->svq))) { 663 if (unlikely(!virtqueue_enable_cb_delayed(vi->svq))) {
666 /* More just got used, free them then recheck. */ 664 /* More just got used, free them then recheck. */
667 capacity += free_old_xmit_skbs(vi); 665 free_old_xmit_skbs(vi);
666 capacity = vi->svq->num_free;
668 if (capacity >= 2+MAX_SKB_FRAGS) { 667 if (capacity >= 2+MAX_SKB_FRAGS) {
669 netif_start_queue(dev); 668 netif_start_queue(dev);
670 virtqueue_disable_cb(vi->svq); 669 virtqueue_disable_cb(vi->svq);