diff options
author | Shirley Ma <mashirle@us.ibm.com> | 2010-01-29 03:19:05 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-02 15:55:42 -0800 |
commit | f9bfbebf34eab707b065116cdc9699d25ba4252a (patch) | |
tree | 8cecf55980c72085dcc6e6af39bdfc7cccf18b69 /drivers/virtio | |
parent | 28aecb9d7728dc26bf03ce7925fe622023a83a2a (diff) | |
download | linux-stable-f9bfbebf34eab707b065116cdc9699d25ba4252a.tar.gz linux-stable-f9bfbebf34eab707b065116cdc9699d25ba4252a.tar.bz2 linux-stable-f9bfbebf34eab707b065116cdc9699d25ba4252a.zip |
virtio: Add ability to detach unused buffers from vrings
There's currently no way for a virtio driver to ask for unused
buffers, so it has to keep a list itself to reclaim them at shutdown.
This is redundant, since virtio_ring stores that information. So
add a new hook to do this.
Signed-off-by: Shirley Ma <xma@us.ibm.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/virtio')
-rw-r--r-- | drivers/virtio/virtio_ring.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index fbd2ecde93e4..71929ee00d69 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -334,6 +334,30 @@ static bool vring_enable_cb(struct virtqueue *_vq) return true; } +static void *vring_detach_unused_buf(struct virtqueue *_vq) +{ + struct vring_virtqueue *vq = to_vvq(_vq); + unsigned int i; + void *buf; + + START_USE(vq); + + for (i = 0; i < vq->vring.num; i++) { + if (!vq->data[i]) + continue; + /* detach_buf clears data, so grab it now. */ + buf = vq->data[i]; + detach_buf(vq, i); + END_USE(vq); + return buf; + } + /* That should have freed everything. */ + BUG_ON(vq->num_free != vq->vring.num); + + END_USE(vq); + return NULL; +} + irqreturn_t vring_interrupt(int irq, void *_vq) { struct vring_virtqueue *vq = to_vvq(_vq); @@ -360,6 +384,7 @@ static struct virtqueue_ops vring_vq_ops = { .kick = vring_kick, .disable_cb = vring_disable_cb, .enable_cb = vring_enable_cb, + .detach_unused_buf = vring_detach_unused_buf, }; struct virtqueue *vring_new_virtqueue(unsigned int num, |