On Mon, Feb 14, 2022 at 4:14 PM Xuan Zhuo <xuanzhuo@xxxxxxxxxxxxxxxxx> wrote: > > The purpose of this patch is to make vring packed support re-enable reset > vq. > > Based on whether the incoming vq passed by vring_setup_virtqueue() is > NULL or not, distinguish whether it is a normal create virtqueue or > re-enable a reset queue. > > When re-enable a reset queue, reuse the original callback, name, indirect. > > Signed-off-by: Xuan Zhuo <xuanzhuo@xxxxxxxxxxxxxxxxx> > --- > drivers/virtio/virtio_ring.c | 29 ++++++++++++++++++----------- > 1 file changed, 18 insertions(+), 11 deletions(-) > > diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c > index 4639e1643c78..20659f7ca582 100644 > --- a/drivers/virtio/virtio_ring.c > +++ b/drivers/virtio/virtio_ring.c > @@ -1683,7 +1683,8 @@ static struct virtqueue *vring_create_virtqueue_packed( > bool context, > bool (*notify)(struct virtqueue *), > void (*callback)(struct virtqueue *), > - const char *name) > + const char *name, > + struct virtqueue *_vq) > { > struct vring_virtqueue *vq; > struct vring_packed_desc *ring; > @@ -1713,13 +1714,20 @@ static struct virtqueue *vring_create_virtqueue_packed( > if (!device) > goto err_device; > > - vq = kmalloc(sizeof(*vq), GFP_KERNEL); > - if (!vq) > - goto err_vq; > + if (_vq) { > + vq = to_vvq(_vq); > + } else { > + vq = kmalloc(sizeof(*vq), GFP_KERNEL); > + if (!vq) > + goto err_vq; > + > + vq->vq.callback = callback; > + vq->vq.name = name; > + vq->indirect = virtio_has_feature(vdev, VIRTIO_RING_F_INDIRECT_DESC) && > + !context; > + } The code looks tricky. Except for the memory we don't even need to touch any of the other attributes. I'd suggest splitting out the vring allocation into a dedicated helper that could be called by both vring_create_queue_XXX and the enable() logic (and in the enable logic we don't even need to relocate if size is not changed). Thanks > > - vq->vq.callback = callback; > vq->vq.vdev = vdev; > - vq->vq.name = name; > vq->vq.num_free = num; > vq->vq.index = index; > vq->we_own_ring = true; > @@ -1736,8 +1744,6 @@ static struct virtqueue *vring_create_virtqueue_packed( > vq->last_add_time_valid = false; > #endif > > - vq->indirect = virtio_has_feature(vdev, VIRTIO_RING_F_INDIRECT_DESC) && > - !context; > vq->event = virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX); > > if (virtio_has_feature(vdev, VIRTIO_F_ORDER_PLATFORM)) > @@ -1778,7 +1784,7 @@ static struct virtqueue *vring_create_virtqueue_packed( > goto err_desc_extra; > > /* No callback? Tell other side not to bother us. */ > - if (!callback) { > + if (!vq->vq.callback) { > vq->packed.event_flags_shadow = VRING_PACKED_EVENT_FLAG_DISABLE; > vq->packed.vring.driver->flags = > cpu_to_le16(vq->packed.event_flags_shadow); > @@ -1792,7 +1798,8 @@ static struct virtqueue *vring_create_virtqueue_packed( > err_desc_extra: > kfree(vq->packed.desc_state); > err_desc_state: > - kfree(vq); > + if (!_vq) > + kfree(vq); > err_vq: > vring_free_queue(vdev, event_size_in_bytes, device, device_event_dma_addr); > err_device: > @@ -2317,7 +2324,7 @@ struct virtqueue *vring_setup_virtqueue( > if (virtio_has_feature(vdev, VIRTIO_F_RING_PACKED)) > return vring_create_virtqueue_packed(index, num, vring_align, > vdev, weak_barriers, may_reduce_num, > - context, notify, callback, name); > + context, notify, callback, name, vq); > > return vring_create_virtqueue_split(index, num, vring_align, > vdev, weak_barriers, may_reduce_num, > -- > 2.31.0 >