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.shah@xxxxxxxxxx> 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.shah@xxxxxxxxxx> --- 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@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/virtualization