[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20220424024044.94749-16-xuanzhuo@linux.alibaba.com>
Date: Sun, 24 Apr 2022 10:40:43 +0800
From: Xuan Zhuo <xuanzhuo@...ux.alibaba.com>
To: linux-kernel@...r.kernel.org
Cc: "Michael S. Tsirkin" <mst@...hat.com>,
Jason Wang <jasowang@...hat.com>,
virtualization@...ts.linux-foundation.org
Subject: [RFC PATCH 15/16] virtio_ring: packed: resize support re-use buffers
Packed vring resize supports reusing the original buffer.
The packed vring resize function implemented earlier uses the method
of letting the upper layer recycle all the buffers. This commit will
first try to re-put it to the new vring in the order submitted to the
old vring. The remaining buffers that cannot be submitted to the new
vring will be called the recycle callback to release.
Signed-off-by: Xuan Zhuo <xuanzhuo@...ux.alibaba.com>
---
drivers/virtio/virtio_ring.c | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 66f71e22ece0..730c8dded4c7 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -217,7 +217,6 @@ struct vring_virtqueue {
};
static struct vring_desc_extra *vring_alloc_desc_extra(unsigned int num);
-static void vring_free(struct virtqueue *_vq);
/*
* Helpers.
@@ -2357,11 +2356,13 @@ static struct virtqueue *vring_create_virtqueue_packed(
return NULL;
}
-static int virtqueue_resize_packed(struct virtqueue *_vq, u32 num)
+static int virtqueue_resize_packed(struct virtqueue *_vq, u32 num,
+ void (*recycle)(struct virtqueue *vq, void *buf))
{
- struct vring_virtqueue_packed vring = {};
+ struct vring_virtqueue_packed vring = {}, vring_old = {};
struct vring_virtqueue *vq = to_vvq(_vq);
struct virtio_device *vdev = _vq->vdev;
+ void *buf;
int err;
if (vring_alloc_queue_packed(&vring, vdev, num))
@@ -2371,17 +2372,28 @@ static int virtqueue_resize_packed(struct virtqueue *_vq, u32 num)
if (err)
goto err_state_extra;
- vring_free(&vq->vq);
+ vring_virtqueue_detach_packed(vq, &vring_old);
virtqueue_init(vq, vring.vring.num);
virtqueue_vring_attach_packed(vq, &vring);
virtqueue_vring_init_packed(vq);
+ vring_reuse_bufs_packed(vq, &vring_old, recycle);
+ vring_free_packed(&vring_old, vdev);
+
return 0;
err_state_extra:
vring_free_packed(&vring, vdev);
err_ring:
+ /*
+ * In the case of failure to create vring, do not try to reuse the
+ * original buffer. Because the probability of this situation is not
+ * high, but we have to introduce new logic.
+ */
+ while ((buf = virtqueue_detach_unused_buf(&vq->vq)))
+ recycle(&vq->vq, buf);
+
virtqueue_reinit_packed(vq);
return -ENOMEM;
}
@@ -2914,7 +2926,7 @@ int virtqueue_resize(struct virtqueue *_vq, u32 num,
recycle(_vq, buf);
if (packed)
- err = virtqueue_resize_packed(_vq, num);
+ err = virtqueue_resize_packed(_vq, num, recycle);
else
err = virtqueue_resize_split(_vq, num, recycle);
--
2.31.0
Powered by blists - more mailing lists