On Fri, 12 Aug 2016 16:32:57 +0100 Stefan Hajnoczi <stefa...@redhat.com> wrote:
> virtqueue_discard() requires a VirtQueueElement but virtio-balloon does > not migrate its in-use element. Introduce a new function that is > similar to virtqueue_discard() but doesn't require a VirtQueueElement. > > This will allow virtio-balloon to access element again after migration > with the usual proviso that the guest may have modified the vring since > last time. > > Signed-off-by: Stefan Hajnoczi <stefa...@redhat.com> > --- > hw/virtio/virtio.c | 22 ++++++++++++++++++++++ > include/hw/virtio/virtio.h | 1 + > 2 files changed, 23 insertions(+) > > diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c > index 00158b6..22727ba 100644 > --- a/hw/virtio/virtio.c > +++ b/hw/virtio/virtio.c > @@ -272,6 +272,28 @@ void virtqueue_discard(VirtQueue *vq, const > VirtQueueElement *elem, > virtqueue_unmap_sg(vq, elem, len); > } > > +/* virtqueue_rewind: > + * @vq: The #VirtQueue > + * @num: Number of elements to push back > + * > + * Pretend that elements weren't popped from the virtqueue. The next > + * virtqueue_pop() will refetch the oldest element. > + * > + * Use virtqueue_discard() instead if you have a VirtQueueElement. > + * > + * Returns: true on success, false if @num is greater than the number of in > use > + * elements. Does it make sense at all to rewind multiple elements at once? Or does it make more sense for the caller to rewind one-by-one until they know that there are no more elements that could be refetched? > + */ > +bool virtqueue_rewind(VirtQueue *vq, unsigned int num) > +{ > + if (num > vq->inuse) { > + return false; > + } > + vq->last_avail_idx -= num; > + vq->inuse -= num; > + return true; > +} > + > void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem, > unsigned int len, unsigned int idx) > {