netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: Krishna Kumar <krkumar2@in.ibm.com>
Cc: davem@davemloft.net, eric.dumazet@gmail.com, kvm@vger.kernel.org,
	netdev@vger.kernel.org, rusty@rustcorp.com.au
Subject: Re: [PATCH 3/4] [RFC] virtio-net: Changes to virtio-net driver
Date: Thu, 5 May 2011 15:28:32 +0300	[thread overview]
Message-ID: <20110505122832.GE17647@redhat.com> (raw)
In-Reply-To: <20110504140332.14817.91910.sendpatchset@krkumar2.in.ibm.com>

On Wed, May 04, 2011 at 07:33:32PM +0530, Krishna Kumar wrote:
> Changes:
> 
> 1. Remove xmit notification
> 2. free_old_xmit_skbs() frees upto a limit to reduce tx jitter.
> 3. xmit_skb() precalculates the number of slots and checks if
>    that is available. It assumes that we are not using
>    indirect descriptors at this time.
> 4. start_xmit() becomes a small routine that removes most error
>    checks, does not drop packets but instead returns EBUSY if
>    there is no space to transmit. It also sets when to restart
>    xmits in future.
> 
> Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
> ---
>  drivers/net/virtio_net.c |   70 ++++++++++---------------------------
>  1 file changed, 20 insertions(+), 50 deletions(-)
> 
> diff -ruNp org/drivers/net/virtio_net.c new/drivers/net/virtio_net.c
> --- org/drivers/net/virtio_net.c	2011-05-04 18:57:06.000000000 +0530
> +++ new/drivers/net/virtio_net.c	2011-05-04 18:57:09.000000000 +0530
> @@ -117,17 +117,6 @@ static struct page *get_a_page(struct vi
>  	return p;
>  }
>  
> -static void skb_xmit_done(struct virtqueue *svq)
> -{
> -	struct virtnet_info *vi = svq->vdev->priv;
> -
> -	/* Suppress further interrupts. */
> -	virtqueue_disable_cb(svq);
> -
> -	/* We were probably waiting for more output buffers. */
> -	netif_wake_queue(vi->dev);
> -}
> -
>  static void set_skb_frag(struct sk_buff *skb, struct page *page,
>  			 unsigned int offset, unsigned int *len)
>  {
> @@ -509,19 +498,18 @@ again:
>  	return received;
>  }
>  
> -static unsigned int free_old_xmit_skbs(struct virtnet_info *vi)
> +static inline void free_old_xmit_skbs(struct virtnet_info *vi)
>  {
>  	struct sk_buff *skb;
> -	unsigned int len, tot_sgs = 0;
> +	unsigned int count = 0, len;
>  
> -	while ((skb = virtqueue_get_buf(vi->svq, &len)) != NULL) {
> +	while (count++ < MAX_SKB_FRAGS+2 &&
> +	       (skb = virtqueue_get_buf(vi->svq, &len)) != NULL) {
>  		pr_debug("Sent skb %p\n", skb);
>  		vi->dev->stats.tx_bytes += skb->len;
>  		vi->dev->stats.tx_packets++;
> -		tot_sgs += skb_vnet_hdr(skb)->num_sg;
>  		dev_kfree_skb_any(skb);
>  	}
> -	return tot_sgs;
>  }
>  
>  static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
> @@ -531,6 +519,12 @@ static int xmit_skb(struct virtnet_info 
>  
>  	pr_debug("%s: xmit %p %pM\n", vi->dev->name, skb, dest);
>  
> +	hdr->num_sg = skb_to_sgvec(skb, vi->tx_sg + 1, 0, skb->len) + 1;
> +	if (unlikely(hdr->num_sg > virtqueue_get_capacity(vi->svq))) {
> +		/* Don't rely on indirect descriptors when reaching capacity */
> +		return -ENOSPC;
> +	}
> +

This is minor, but when the ring gets full, we are doing extra
work.

>  	if (skb->ip_summed == CHECKSUM_PARTIAL) {
>  		hdr->hdr.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
>  		hdr->hdr.csum_start = skb_checksum_start_offset(skb);
> @@ -566,7 +560,6 @@ static int xmit_skb(struct virtnet_info 
>  	else
>  		sg_set_buf(vi->tx_sg, &hdr->hdr, sizeof hdr->hdr);
>  
> -	hdr->num_sg = skb_to_sgvec(skb, vi->tx_sg + 1, 0, skb->len) + 1;
>  	return virtqueue_add_buf(vi->svq, vi->tx_sg, hdr->num_sg,
>  					0, skb);
>  }
> @@ -574,30 +567,21 @@ static int xmit_skb(struct virtnet_info 
>  static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
>  {
>  	struct virtnet_info *vi = netdev_priv(dev);
> -	int capacity;
>  
>  	/* Free up any pending old buffers before queueing new ones. */
>  	free_old_xmit_skbs(vi);
>  
>  	/* Try to transmit */
> -	capacity = xmit_skb(vi, skb);
> +	if (unlikely(xmit_skb(vi, skb) < 0)) {
> +		struct netdev_queue *txq;
>  
> -	/* This can happen with OOM and indirect buffers. */
> -	if (unlikely(capacity < 0)) {
> -		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);
> -			}
> -		}
> -		dev->stats.tx_dropped++;
> -		kfree_skb(skb);
> -		return NETDEV_TX_OK;
> +		/*
> +		 * Tell kernel to restart xmits after 1 jiffy to help the
> +		 * host catch up.
> +		 */
> +		txq = netdev_get_tx_queue(dev, 0);
> +		txq->xmit_restart_jiffies = jiffies + 1;
> +		return NETDEV_TX_BUSY;
>  	}
>  	virtqueue_kick(vi->svq);
>  
> @@ -605,20 +589,6 @@ static netdev_tx_t start_xmit(struct sk_
>  	skb_orphan(skb);
>  	nf_reset(skb);
>  
> -	/* Apparently nice girls don't return TX_BUSY; stop the queue
> -	 * before it gets out of hand.  Naturally, this wastes entries. */
> -	if (capacity < 2+MAX_SKB_FRAGS) {
> -		netif_stop_queue(dev);
> -		if (unlikely(!virtqueue_enable_cb(vi->svq))) {
> -			/* More just got used, free them then recheck. */
> -			capacity += free_old_xmit_skbs(vi);
> -			if (capacity >= 2+MAX_SKB_FRAGS) {
> -				netif_start_queue(dev);
> -				virtqueue_disable_cb(vi->svq);
> -			}
> -		}
> -	}
> -
>  	return NETDEV_TX_OK;
>  }
>  
> @@ -881,7 +851,7 @@ static int virtnet_probe(struct virtio_d
>  	struct net_device *dev;
>  	struct virtnet_info *vi;
>  	struct virtqueue *vqs[3];
> -	vq_callback_t *callbacks[] = { skb_recv_done, skb_xmit_done, NULL};
> +	vq_callback_t *callbacks[] = { skb_recv_done, NULL, NULL};
>  	const char *names[] = { "input", "output", "control" };
>  	int nvqs;
>  

  reply	other threads:[~2011-05-05 12:28 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-04 14:02 [PATCH 0/4] [RFC] virtio-net: Improve small packet performance Krishna Kumar
2011-05-04 14:03 ` [PATCH 1/4] [RFC] netdevice: Introduce per-txq xmit_restart Krishna Kumar
2011-05-04 14:03 ` [PATCH 2/4] [RFC] virtio: Introduce new API to get free space Krishna Kumar
2011-05-04 14:50   ` Michael S. Tsirkin
2011-05-04 20:00     ` Michael S. Tsirkin
2011-05-05  3:08       ` Krishna Kumar2
2011-05-05  9:13       ` Michael S. Tsirkin
2011-05-04 19:58   ` Michael S. Tsirkin
2011-05-04 14:03 ` [PATCH 3/4] [RFC] virtio-net: Changes to virtio-net driver Krishna Kumar
2011-05-05 12:28   ` Michael S. Tsirkin [this message]
2011-05-04 14:03 ` [PATCH 4/4] [RFC] sched: Changes to dequeue_skb Krishna Kumar
2011-05-04 14:46 ` [PATCH 0/4] [RFC] virtio-net: Improve small packet performance Michael S. Tsirkin
2011-05-04 14:59   ` Krishna Kumar2
2011-05-04 21:23     ` Michael S. Tsirkin
2011-05-05  8:03       ` Krishna Kumar2
2011-05-05  9:04         ` Michael S. Tsirkin
2011-05-05  9:43           ` Krishna Kumar2
2011-05-05 10:12             ` Michael S. Tsirkin
2011-05-05 10:57               ` Krishna Kumar2
2011-05-05 15:27           ` Krishna Kumar2
2011-05-05 15:34             ` Michael S. Tsirkin
2011-05-07  7:15               ` Krishna Kumar2
2011-05-05 15:36             ` Krishna Kumar2
2011-05-05 15:37               ` Michael S. Tsirkin
2011-05-05 15:42             ` Michael S. Tsirkin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110505122832.GE17647@redhat.com \
    --to=mst@redhat.com \
    --cc=davem@davemloft.net \
    --cc=eric.dumazet@gmail.com \
    --cc=krkumar2@in.ibm.com \
    --cc=kvm@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=rusty@rustcorp.com.au \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).