Commit f9bfbebf34eab707b065116cdc9699d25ba4252a
Committed by
David S. Miller
1 parent
28aecb9d77
Exists in
master
and in
7 other branches
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>
Showing 2 changed files with 29 additions and 0 deletions Side-by-side Diff
drivers/virtio/virtio_ring.c
... | ... | @@ -334,6 +334,30 @@ |
334 | 334 | return true; |
335 | 335 | } |
336 | 336 | |
337 | +static void *vring_detach_unused_buf(struct virtqueue *_vq) | |
338 | +{ | |
339 | + struct vring_virtqueue *vq = to_vvq(_vq); | |
340 | + unsigned int i; | |
341 | + void *buf; | |
342 | + | |
343 | + START_USE(vq); | |
344 | + | |
345 | + for (i = 0; i < vq->vring.num; i++) { | |
346 | + if (!vq->data[i]) | |
347 | + continue; | |
348 | + /* detach_buf clears data, so grab it now. */ | |
349 | + buf = vq->data[i]; | |
350 | + detach_buf(vq, i); | |
351 | + END_USE(vq); | |
352 | + return buf; | |
353 | + } | |
354 | + /* That should have freed everything. */ | |
355 | + BUG_ON(vq->num_free != vq->vring.num); | |
356 | + | |
357 | + END_USE(vq); | |
358 | + return NULL; | |
359 | +} | |
360 | + | |
337 | 361 | irqreturn_t vring_interrupt(int irq, void *_vq) |
338 | 362 | { |
339 | 363 | struct vring_virtqueue *vq = to_vvq(_vq); |
... | ... | @@ -360,6 +384,7 @@ |
360 | 384 | .kick = vring_kick, |
361 | 385 | .disable_cb = vring_disable_cb, |
362 | 386 | .enable_cb = vring_enable_cb, |
387 | + .detach_unused_buf = vring_detach_unused_buf, | |
363 | 388 | }; |
364 | 389 | |
365 | 390 | struct virtqueue *vring_new_virtqueue(unsigned int num, |
include/linux/virtio.h
... | ... | @@ -51,6 +51,9 @@ |
51 | 51 | * This re-enables callbacks; it returns "false" if there are pending |
52 | 52 | * buffers in the queue, to detect a possible race between the driver |
53 | 53 | * checking for more work, and enabling callbacks. |
54 | + * @detach_unused_buf: detach first unused buffer | |
55 | + * vq: the struct virtqueue we're talking about. | |
56 | + * Returns NULL or the "data" token handed to add_buf | |
54 | 57 | * |
55 | 58 | * Locking rules are straightforward: the driver is responsible for |
56 | 59 | * locking. No two operations may be invoked simultaneously, with the exception |
... | ... | @@ -71,6 +74,7 @@ |
71 | 74 | |
72 | 75 | void (*disable_cb)(struct virtqueue *vq); |
73 | 76 | bool (*enable_cb)(struct virtqueue *vq); |
77 | + void *(*detach_unused_buf)(struct virtqueue *vq); | |
74 | 78 | }; |
75 | 79 | |
76 | 80 | /** |