On (Sat) Aug 22 2009 [17:31:26], Rusty Russell wrote:
> On Wed, 19 Aug 2009 01:31:29 am Amit Shah wrote:
> > This helper returns 1 if a call to add_buf will not fail
> > with -ENOSPC.
> > 
> > This will help callers that do
> > 
> > while(1) {
> >     alloc()
> >     if (add_buf()) {
> >             free();
> >             break;
> >     }
> > }
> > 
> > This will result in one less alloc/free exercise.
> 
> Hi Amit,
> 
>     This is what I have in my tree; similar motivation.  I didn't
> adapt virtio_net like you did tho.

Hi Rusty,

This works too. A simple (untested) patch to make virtio_net use it:


>From a252db16c737b608efffcec22cade1c914dfe859 Mon Sep 17 00:00:00 2001
From: Amit Shah <amit.s...@redhat.com>
Date: Mon, 24 Aug 2009 13:07:04 +0530
Subject: [PATCH] virtio_net: Check for room in the vq before adding buffer

Saves us one cycle of alloc-add-free if the queue
was full.

Signed-off-by: Amit Shah <amit.s...@redhat.com>
---
 drivers/net/virtio_net.c |   18 ++++++++++--------
 1 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index e94f817..1f45a10 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -276,11 +276,12 @@ static bool try_fill_recv_maxbufs(struct virtnet_info 
*vi, gfp_t gfp)
 {
        struct sk_buff *skb;
        struct scatterlist sg[2+MAX_SKB_FRAGS];
-       int num, err, i;
+       int num, ret, i;
        bool oom = false;
 
        sg_init_table(sg, 2+MAX_SKB_FRAGS);
-       for (;;) {
+       ret = 1;
+       while(ret > 0) { /* Is there space to add another buffer to the vq */
                struct skb_vnet_hdr *hdr;
 
                skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN + NET_IP_ALIGN);
@@ -315,8 +316,8 @@ static bool try_fill_recv_maxbufs(struct virtnet_info *vi, 
gfp_t gfp)
                num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
                skb_queue_head(&vi->recv, skb);
 
-               err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, num, skb);
-               if (err < 0) {
+               ret = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, num, skb);
+               if (ret < 0) {
                        skb_unlink(skb, &vi->recv);
                        trim_pages(vi, skb);
                        kfree_skb(skb);
@@ -335,13 +336,14 @@ static bool try_fill_recv(struct virtnet_info *vi, gfp_t 
gfp)
 {
        struct sk_buff *skb;
        struct scatterlist sg[1];
-       int err;
+       int ret;
        bool oom = false;
 
        if (!vi->mergeable_rx_bufs)
                return try_fill_recv_maxbufs(vi, gfp);
 
-       for (;;) {
+       ret = 1;
+       while(ret > 0) { /* Is there space to add another buffer to the vq */
                skb_frag_t *f;
 
                skb = netdev_alloc_skb(vi->dev, GOOD_COPY_LEN + NET_IP_ALIGN);
@@ -368,8 +370,8 @@ static bool try_fill_recv(struct virtnet_info *vi, gfp_t 
gfp)
                sg_init_one(sg, page_address(f->page), PAGE_SIZE);
                skb_queue_head(&vi->recv, skb);
 
-               err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, 1, skb);
-               if (err < 0) {
+               ret = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, 1, skb);
+               if (ret < 0) {
                        skb_unlink(skb, &vi->recv);
                        kfree_skb(skb);
                        break;
-- 
1.6.2.5


                Amit
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization

Reply via email to