mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-30 14:19:16 +00:00
virtio_ring: packed: extract the logic of alloc state and extra
Separate the logic for alloc desc_state and desc_extra, which will be called separately by subsequent patches. Use struct vring_packed to pass desc_state, desc_extra. Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Acked-by: Jason Wang <jasowang@redhat.com> Message-Id: <20220801063902.129329-20-xuanzhuo@linux.alibaba.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
6b60b9c008
commit
ef3167cfd5
1 changed files with 34 additions and 14 deletions
|
@ -1905,6 +1905,33 @@ static int vring_alloc_queue_packed(struct vring_virtqueue_packed *vring_packed,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int vring_alloc_state_extra_packed(struct vring_virtqueue_packed *vring_packed)
|
||||
{
|
||||
struct vring_desc_state_packed *state;
|
||||
struct vring_desc_extra *extra;
|
||||
u32 num = vring_packed->vring.num;
|
||||
|
||||
state = kmalloc_array(num, sizeof(struct vring_desc_state_packed), GFP_KERNEL);
|
||||
if (!state)
|
||||
goto err_desc_state;
|
||||
|
||||
memset(state, 0, num * sizeof(struct vring_desc_state_packed));
|
||||
|
||||
extra = vring_alloc_desc_extra(num);
|
||||
if (!extra)
|
||||
goto err_desc_extra;
|
||||
|
||||
vring_packed->desc_state = state;
|
||||
vring_packed->desc_extra = extra;
|
||||
|
||||
return 0;
|
||||
|
||||
err_desc_extra:
|
||||
kfree(state);
|
||||
err_desc_state:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static struct virtqueue *vring_create_virtqueue_packed(
|
||||
unsigned int index,
|
||||
unsigned int num,
|
||||
|
@ -1919,6 +1946,7 @@ static struct virtqueue *vring_create_virtqueue_packed(
|
|||
{
|
||||
struct vring_virtqueue_packed vring_packed = {};
|
||||
struct vring_virtqueue *vq;
|
||||
int err;
|
||||
|
||||
if (vring_alloc_queue_packed(&vring_packed, vdev, num))
|
||||
goto err_ring;
|
||||
|
@ -1963,21 +1991,15 @@ static struct virtqueue *vring_create_virtqueue_packed(
|
|||
vq->packed.event_flags_shadow = 0;
|
||||
vq->packed.avail_used_flags = 1 << VRING_PACKED_DESC_F_AVAIL;
|
||||
|
||||
vq->packed.desc_state = kmalloc_array(num,
|
||||
sizeof(struct vring_desc_state_packed),
|
||||
GFP_KERNEL);
|
||||
if (!vq->packed.desc_state)
|
||||
goto err_desc_state;
|
||||
|
||||
memset(vq->packed.desc_state, 0,
|
||||
num * sizeof(struct vring_desc_state_packed));
|
||||
err = vring_alloc_state_extra_packed(&vring_packed);
|
||||
if (err)
|
||||
goto err_state_extra;
|
||||
|
||||
/* Put everything in free lists. */
|
||||
vq->free_head = 0;
|
||||
|
||||
vq->packed.desc_extra = vring_alloc_desc_extra(num);
|
||||
if (!vq->packed.desc_extra)
|
||||
goto err_desc_extra;
|
||||
vq->packed.desc_state = vring_packed.desc_state;
|
||||
vq->packed.desc_extra = vring_packed.desc_extra;
|
||||
|
||||
/* No callback? Tell other side not to bother us. */
|
||||
if (!callback) {
|
||||
|
@ -1993,9 +2015,7 @@ static struct virtqueue *vring_create_virtqueue_packed(
|
|||
spin_unlock(&vdev->vqs_list_lock);
|
||||
return &vq->vq;
|
||||
|
||||
err_desc_extra:
|
||||
kfree(vq->packed.desc_state);
|
||||
err_desc_state:
|
||||
err_state_extra:
|
||||
kfree(vq);
|
||||
err_vq:
|
||||
vring_free_packed(&vring_packed, vdev);
|
||||
|
|
Loading…
Reference in a new issue