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

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
......@@ -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,
struct virtio_device *vdev,
bool weak_barriers,
bool may_reduce_num,
bool context,
bool (*notify)(struct virtqueue *),
void (*callback)(struct virtqueue *),
const char *name)
static int vring_alloc_queue_split(struct vring_virtqueue_split *vring_split,
struct virtio_device *vdev,
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;
vring_init(&vring_split->vring, num, queue, vring_align);
queue_size_in_bytes = vring_size(num, 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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment