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;
>
next prev parent 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).