Commit ad48d53b authored by Xuan Zhuo's avatar Xuan Zhuo Committed by Michael S. Tsirkin
Browse files

virtio_ring: separate the logic of reset/enable from virtqueue_resize



The subsequent reset function will reuse these logic.

Signed-off-by: default avatarXuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: default avatarJason Wang <jasowang@redhat.com>
Message-Id: <20230810123057.43407-9-xuanzhuo@linux.alibaba.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 4d09f240
Loading
Loading
Loading
Loading
+39 −19
Original line number Diff line number Diff line
@@ -2152,6 +2152,43 @@ static int virtqueue_resize_packed(struct virtqueue *_vq, u32 num)
	return -ENOMEM;
}

static int virtqueue_disable_and_recycle(struct virtqueue *_vq,
					 void (*recycle)(struct virtqueue *vq, void *buf))
{
	struct vring_virtqueue *vq = to_vvq(_vq);
	struct virtio_device *vdev = vq->vq.vdev;
	void *buf;
	int err;

	if (!vq->we_own_ring)
		return -EPERM;

	if (!vdev->config->disable_vq_and_reset)
		return -ENOENT;

	if (!vdev->config->enable_vq_after_reset)
		return -ENOENT;

	err = vdev->config->disable_vq_and_reset(_vq);
	if (err)
		return err;

	while ((buf = virtqueue_detach_unused_buf(_vq)) != NULL)
		recycle(_vq, buf);

	return 0;
}

static int virtqueue_enable_after_reset(struct virtqueue *_vq)
{
	struct vring_virtqueue *vq = to_vvq(_vq);
	struct virtio_device *vdev = vq->vq.vdev;

	if (vdev->config->enable_vq_after_reset(_vq))
		return -EBUSY;

	return 0;
}

/*
 * Generic functions and exported symbols.
@@ -2702,13 +2739,8 @@ int virtqueue_resize(struct virtqueue *_vq, u32 num,
		     void (*recycle)(struct virtqueue *vq, void *buf))
{
	struct vring_virtqueue *vq = to_vvq(_vq);
	struct virtio_device *vdev = vq->vq.vdev;
	void *buf;
	int err;

	if (!vq->we_own_ring)
		return -EPERM;

	if (num > vq->vq.num_max)
		return -E2BIG;

@@ -2718,28 +2750,16 @@ int virtqueue_resize(struct virtqueue *_vq, u32 num,
	if ((vq->packed_ring ? vq->packed.vring.num : vq->split.vring.num) == num)
		return 0;

	if (!vdev->config->disable_vq_and_reset)
		return -ENOENT;

	if (!vdev->config->enable_vq_after_reset)
		return -ENOENT;

	err = vdev->config->disable_vq_and_reset(_vq);
	err = virtqueue_disable_and_recycle(_vq, recycle);
	if (err)
		return err;

	while ((buf = virtqueue_detach_unused_buf(_vq)) != NULL)
		recycle(_vq, buf);

	if (vq->packed_ring)
		err = virtqueue_resize_packed(_vq, num);
	else
		err = virtqueue_resize_split(_vq, num);

	if (vdev->config->enable_vq_after_reset(_vq))
		return -EBUSY;

	return err;
	return virtqueue_enable_after_reset(_vq);
}
EXPORT_SYMBOL_GPL(virtqueue_resize);