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

virtio_ring: split: extract the logic of alloc queue



Separate the logic of split to create vring queue.

This feature is required for subsequent virtuqueue reset vring.

Signed-off-by: default avatarXuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: default avatarJason Wang <jasowang@redhat.com>
Message-Id: <20220801063902.129329-11-xuanzhuo@linux.alibaba.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 89f05d94
Loading
Loading
Loading
Loading
+40 −25
Original line number Diff line number Diff line
@@ -948,29 +948,19 @@ static void vring_free_split(struct vring_virtqueue_split *vring_split,
	kfree(vring_split->desc_extra);
}

static struct virtqueue *vring_create_virtqueue_split(
	unsigned int index,
	unsigned int num,
	unsigned int vring_align,
static int vring_alloc_queue_split(struct vring_virtqueue_split *vring_split,
				   struct virtio_device *vdev,
	bool weak_barriers,
	bool may_reduce_num,
	bool context,
	bool (*notify)(struct virtqueue *),
	void (*callback)(struct virtqueue *),
	const char *name)
				   u32 num,
				   unsigned int vring_align,
				   bool may_reduce_num)
{
	struct vring_virtqueue_split vring_split = {};
	struct virtqueue *vq;
	void *queue = NULL;
	dma_addr_t dma_addr;
	size_t queue_size_in_bytes;
	struct vring vring;

	/* We assume num is a power of 2. */
	if (num & (num - 1)) {
		dev_warn(&vdev->dev, "Bad virtqueue length %u\n", num);
		return NULL;
		return -EINVAL;
	}

	/* TODO: allocate each queue chunk individually */
@@ -981,11 +971,11 @@ static struct virtqueue *vring_create_virtqueue_split(
		if (queue)
			break;
		if (!may_reduce_num)
			return NULL;
			return -ENOMEM;
	}

	if (!num)
		return NULL;
		return -ENOMEM;

	if (!queue) {
		/* Try to get a single page. You are my only hope! */
@@ -993,21 +983,46 @@ static struct virtqueue *vring_create_virtqueue_split(
					  &dma_addr, GFP_KERNEL|__GFP_ZERO);
	}
	if (!queue)
		return NULL;
		return -ENOMEM;

	queue_size_in_bytes = vring_size(num, vring_align);
	vring_init(&vring_split.vring, num, queue, vring_align);
	vring_init(&vring_split->vring, num, queue, vring_align);

	vring_split->queue_dma_addr = dma_addr;
	vring_split->queue_size_in_bytes = vring_size(num, vring_align);

	return 0;
}

static struct virtqueue *vring_create_virtqueue_split(
	unsigned int index,
	unsigned int num,
	unsigned int vring_align,
	struct virtio_device *vdev,
	bool weak_barriers,
	bool may_reduce_num,
	bool context,
	bool (*notify)(struct virtqueue *),
	void (*callback)(struct virtqueue *),
	const char *name)
{
	struct vring_virtqueue_split vring_split = {};
	struct virtqueue *vq;
	int err;

	err = vring_alloc_queue_split(&vring_split, vdev, num, vring_align,
				      may_reduce_num);
	if (err)
		return NULL;

	vq = __vring_new_virtqueue(index, &vring_split, vdev, weak_barriers,
				   context, notify, callback, name);
	if (!vq) {
		vring_free_queue(vdev, queue_size_in_bytes, queue,
				 dma_addr);
		vring_free_split(&vring_split, vdev);
		return NULL;
	}

	to_vvq(vq)->split.queue_dma_addr = dma_addr;
	to_vvq(vq)->split.queue_size_in_bytes = queue_size_in_bytes;
	to_vvq(vq)->split.queue_dma_addr = vring_split.queue_dma_addr;
	to_vvq(vq)->split.queue_size_in_bytes = vring_split.queue_size_in_bytes;
	to_vvq(vq)->we_own_ring = true;

	return vq;