diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2009-09-24 00:26:31 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2009-09-23 08:56:31 -0400 |
commit | 3c1b27d5043086a485f8526353ae9fe37bfa1065 (patch) | |
tree | e3b6eda3c66bcd1fc3af6e7fa6e4e3af77459474 /drivers | |
parent | f68d24082e22ccee3077d11aeb6dc5354f0ca7f1 (diff) |
virtio: make add_buf return capacity remaining
This API change means that virtio_net can tell how much capacity
remains for buffers. It's necessarily fuzzy, since
VIRTIO_RING_F_INDIRECT_DESC means we can fit any number of descriptors
in one, *if* we can kmalloc.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Cc: Dinesh Subhraveti <dineshs@us.ibm.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/virtio_blk.c | 2 | ||||
-rw-r--r-- | drivers/char/hw_random/virtio-rng.c | 2 | ||||
-rw-r--r-- | drivers/char/virtio_console.c | 4 | ||||
-rw-r--r-- | drivers/net/virtio_net.c | 14 | ||||
-rw-r--r-- | drivers/virtio/virtio_balloon.c | 2 | ||||
-rw-r--r-- | drivers/virtio/virtio_ring.c | 6 |
6 files changed, 17 insertions, 13 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index aa1a3d5a3e2b..d739ee4201f9 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -139,7 +139,7 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, | |||
139 | } | 139 | } |
140 | } | 140 | } |
141 | 141 | ||
142 | if (vblk->vq->vq_ops->add_buf(vblk->vq, vblk->sg, out, in, vbr)) { | 142 | if (vblk->vq->vq_ops->add_buf(vblk->vq, vblk->sg, out, in, vbr) < 0) { |
143 | mempool_free(vbr, vblk->pool); | 143 | mempool_free(vbr, vblk->pool); |
144 | return false; | 144 | return false; |
145 | } | 145 | } |
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 32216b623248..b6c24dcc987d 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c | |||
@@ -51,7 +51,7 @@ static void register_buffer(void) | |||
51 | 51 | ||
52 | sg_init_one(&sg, random_data+data_left, RANDOM_DATA_SIZE-data_left); | 52 | sg_init_one(&sg, random_data+data_left, RANDOM_DATA_SIZE-data_left); |
53 | /* There should always be room for one buffer. */ | 53 | /* There should always be room for one buffer. */ |
54 | if (vq->vq_ops->add_buf(vq, &sg, 0, 1, random_data) != 0) | 54 | if (vq->vq_ops->add_buf(vq, &sg, 0, 1, random_data) < 0) |
55 | BUG(); | 55 | BUG(); |
56 | vq->vq_ops->kick(vq); | 56 | vq->vq_ops->kick(vq); |
57 | } | 57 | } |
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index c74dacfa6795..a035ae39a359 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -65,7 +65,7 @@ static int put_chars(u32 vtermno, const char *buf, int count) | |||
65 | 65 | ||
66 | /* add_buf wants a token to identify this buffer: we hand it any | 66 | /* add_buf wants a token to identify this buffer: we hand it any |
67 | * non-NULL pointer, since there's only ever one buffer. */ | 67 | * non-NULL pointer, since there's only ever one buffer. */ |
68 | if (out_vq->vq_ops->add_buf(out_vq, sg, 1, 0, (void *)1) == 0) { | 68 | if (out_vq->vq_ops->add_buf(out_vq, sg, 1, 0, (void *)1) >= 0) { |
69 | /* Tell Host to go! */ | 69 | /* Tell Host to go! */ |
70 | out_vq->vq_ops->kick(out_vq); | 70 | out_vq->vq_ops->kick(out_vq); |
71 | /* Chill out until it's done with the buffer. */ | 71 | /* Chill out until it's done with the buffer. */ |
@@ -85,7 +85,7 @@ static void add_inbuf(void) | |||
85 | sg_init_one(sg, inbuf, PAGE_SIZE); | 85 | sg_init_one(sg, inbuf, PAGE_SIZE); |
86 | 86 | ||
87 | /* We should always be able to add one buffer to an empty queue. */ | 87 | /* We should always be able to add one buffer to an empty queue. */ |
88 | if (in_vq->vq_ops->add_buf(in_vq, sg, 0, 1, inbuf) != 0) | 88 | if (in_vq->vq_ops->add_buf(in_vq, sg, 0, 1, inbuf) < 0) |
89 | BUG(); | 89 | BUG(); |
90 | in_vq->vq_ops->kick(in_vq); | 90 | in_vq->vq_ops->kick(in_vq); |
91 | } | 91 | } |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 32266fb89c20..fbf04a553f5a 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -320,7 +320,7 @@ static bool try_fill_recv_maxbufs(struct virtnet_info *vi, gfp_t gfp) | |||
320 | skb_queue_head(&vi->recv, skb); | 320 | skb_queue_head(&vi->recv, skb); |
321 | 321 | ||
322 | err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, num, skb); | 322 | err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, num, skb); |
323 | if (err) { | 323 | if (err < 0) { |
324 | skb_unlink(skb, &vi->recv); | 324 | skb_unlink(skb, &vi->recv); |
325 | trim_pages(vi, skb); | 325 | trim_pages(vi, skb); |
326 | kfree_skb(skb); | 326 | kfree_skb(skb); |
@@ -373,7 +373,7 @@ static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp) | |||
373 | skb_queue_head(&vi->recv, skb); | 373 | skb_queue_head(&vi->recv, skb); |
374 | 374 | ||
375 | err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, 1, skb); | 375 | err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, 1, skb); |
376 | if (err) { | 376 | if (err < 0) { |
377 | skb_unlink(skb, &vi->recv); | 377 | skb_unlink(skb, &vi->recv); |
378 | kfree_skb(skb); | 378 | kfree_skb(skb); |
379 | break; | 379 | break; |
@@ -527,7 +527,7 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) | |||
527 | num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; | 527 | num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; |
528 | 528 | ||
529 | err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); | 529 | err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); |
530 | if (!err && !vi->free_in_tasklet) | 530 | if (err >= 0 && !vi->free_in_tasklet) |
531 | mod_timer(&vi->xmit_free_timer, jiffies + (HZ/10)); | 531 | mod_timer(&vi->xmit_free_timer, jiffies + (HZ/10)); |
532 | 532 | ||
533 | return err; | 533 | return err; |
@@ -538,7 +538,7 @@ static void xmit_tasklet(unsigned long data) | |||
538 | struct virtnet_info *vi = (void *)data; | 538 | struct virtnet_info *vi = (void *)data; |
539 | 539 | ||
540 | netif_tx_lock_bh(vi->dev); | 540 | netif_tx_lock_bh(vi->dev); |
541 | if (vi->last_xmit_skb && xmit_skb(vi, vi->last_xmit_skb) == 0) { | 541 | if (vi->last_xmit_skb && xmit_skb(vi, vi->last_xmit_skb) >= 0) { |
542 | vi->svq->vq_ops->kick(vi->svq); | 542 | vi->svq->vq_ops->kick(vi->svq); |
543 | vi->last_xmit_skb = NULL; | 543 | vi->last_xmit_skb = NULL; |
544 | } | 544 | } |
@@ -557,7 +557,7 @@ again: | |||
557 | 557 | ||
558 | /* If we has a buffer left over from last time, send it now. */ | 558 | /* If we has a buffer left over from last time, send it now. */ |
559 | if (unlikely(vi->last_xmit_skb) && | 559 | if (unlikely(vi->last_xmit_skb) && |
560 | xmit_skb(vi, vi->last_xmit_skb) != 0) | 560 | xmit_skb(vi, vi->last_xmit_skb) < 0) |
561 | goto stop_queue; | 561 | goto stop_queue; |
562 | 562 | ||
563 | vi->last_xmit_skb = NULL; | 563 | vi->last_xmit_skb = NULL; |
@@ -565,7 +565,7 @@ again: | |||
565 | /* Put new one in send queue and do transmit */ | 565 | /* Put new one in send queue and do transmit */ |
566 | if (likely(skb)) { | 566 | if (likely(skb)) { |
567 | __skb_queue_head(&vi->send, skb); | 567 | __skb_queue_head(&vi->send, skb); |
568 | if (xmit_skb(vi, skb) != 0) { | 568 | if (xmit_skb(vi, skb) < 0) { |
569 | vi->last_xmit_skb = skb; | 569 | vi->last_xmit_skb = skb; |
570 | skb = NULL; | 570 | skb = NULL; |
571 | goto stop_queue; | 571 | goto stop_queue; |
@@ -668,7 +668,7 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd, | |||
668 | sg_set_buf(&sg[i + 1], sg_virt(s), s->length); | 668 | sg_set_buf(&sg[i + 1], sg_virt(s), s->length); |
669 | sg_set_buf(&sg[out + in - 1], &status, sizeof(status)); | 669 | sg_set_buf(&sg[out + in - 1], &status, sizeof(status)); |
670 | 670 | ||
671 | BUG_ON(vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi)); | 671 | BUG_ON(vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi) < 0); |
672 | 672 | ||
673 | vi->cvq->vq_ops->kick(vi->cvq); | 673 | vi->cvq->vq_ops->kick(vi->cvq); |
674 | 674 | ||
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 26b278264796..39789232646d 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
@@ -84,7 +84,7 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq) | |||
84 | init_completion(&vb->acked); | 84 | init_completion(&vb->acked); |
85 | 85 | ||
86 | /* We should always be able to add one buffer to an empty queue. */ | 86 | /* We should always be able to add one buffer to an empty queue. */ |
87 | if (vq->vq_ops->add_buf(vq, &sg, 1, 0, vb) != 0) | 87 | if (vq->vq_ops->add_buf(vq, &sg, 1, 0, vb) < 0) |
88 | BUG(); | 88 | BUG(); |
89 | vq->vq_ops->kick(vq); | 89 | vq->vq_ops->kick(vq); |
90 | 90 | ||
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index a882f2606515..f53600580726 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
@@ -208,7 +208,11 @@ add_head: | |||
208 | 208 | ||
209 | pr_debug("Added buffer head %i to %p\n", head, vq); | 209 | pr_debug("Added buffer head %i to %p\n", head, vq); |
210 | END_USE(vq); | 210 | END_USE(vq); |
211 | return 0; | 211 | |
212 | /* If we're indirect, we can fit many (assuming not OOM). */ | ||
213 | if (vq->indirect) | ||
214 | return vq->num_free ? vq->vring.num : 0; | ||
215 | return vq->num_free; | ||
212 | } | 216 | } |
213 | 217 | ||
214 | static void vring_kick(struct virtqueue *_vq) | 218 | static void vring_kick(struct virtqueue *_vq) |