[PATCH] virtio_ring: reset IN_ORDER state in virtqueue_init()

Subsystems: the rest, virtio core

COOLING12d

4 messages, 3 authors, 12d ago · open the first message on its own page

[PATCH] virtio_ring: reset IN_ORDER state in virtqueue_init()

From: lirongqing <hidden>
Date: 2026-09-10 12:39:28

From: Li RongQing <redacted>

The IN_ORDER feature uses additional software state to track the next
available descriptor and in-flight descriptor batches.

virtqueue_init() resets the common virtqueue state, but free_head and
batch_last.id are initialized only when the virtqueue is created. When
an IN_ORDER virtqueue is reset, these fields can retain state from the
previous queue instance.

Reset free_head and invalidate batch_last when initializing an IN_ORDER
virtqueue. Keep this in virtqueue_init() so the state is initialized
consistently for both newly created and reset virtqueues.

Fixes: f6a15d854986 ("virtio_ring: add in order support")
Signed-off-by: Li RongQing <redacted>
---
 drivers/virtio/virtio_ring.c | 5 +++++
 1 file changed, 5 insertions(+)
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index db678f5..d0dc464 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -559,6 +559,11 @@ static void virtqueue_init(struct vring_virtqueue *vq, u32 num)
 	vq->in_use = false;
 	vq->last_add_time_valid = false;
 #endif
+
+	if (virtqueue_is_in_order(vq)) {
+		vq->free_head = 0;
+		vq->batch_last.id = UINT_MAX;
+	}
 }
 
 
-- 
2.9.4

Re: [PATCH] virtio_ring: reset IN_ORDER state in virtqueue_init()

From: sashiko-bot@kernel.org
Date: 2026-09-10 12:56:11

From: Li RongQing <redacted>

The IN_ORDER feature uses additional software state to track the next
available descriptor and in-flight descriptor batches.

virtqueue_init() resets the common virtqueue state, but free_head and
batch_last.id are initialized only when the virtqueue is created. When
an IN_ORDER virtqueue is reset, these fields can retain state from the
previous queue instance.

Reset free_head and invalidate batch_last when initializing an IN_ORDER
virtqueue. Keep this in virtqueue_init() so the state is initialized
consistently for both newly created and reset virtqueues.

Fixes: f6a15d854986 ("virtio_ring: add in order support")
Signed-off-by: Li RongQing <redacted>
Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260910123903.1717-1-lirongqing@baidu.com?part=1

Re: [PATCH] virtio_ring: reset IN_ORDER state in virtqueue_init()

From: Jason Wang <jasowangio@gmail.com>
Date: 2026-09-11 02:18:07

On Thu, Sep 10, 2026 at 8:39 PM lirongqing [off-list ref] wrote:
From: Li RongQing <redacted>

The IN_ORDER feature uses additional software state to track the next
available descriptor and in-flight descriptor batches.

virtqueue_init() resets the common virtqueue state, but free_head and
batch_last.id are initialized only when the virtqueue is created. When
an IN_ORDER virtqueue is reset, these fields can retain state from the
previous queue instance.

Reset free_head and invalidate batch_last when initializing an IN_ORDER
virtqueue. Keep this in virtqueue_init() so the state is initialized
consistently for both newly created and reset virtqueues.

Fixes: f6a15d854986 ("virtio_ring: add in order support")
I think this is needed for -stable.
quoted hunk
Signed-off-by: Li RongQing <redacted>
---
 drivers/virtio/virtio_ring.c | 5 +++++
 1 file changed, 5 insertions(+)
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index db678f5..d0dc464 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -559,6 +559,11 @@ static void virtqueue_init(struct vring_virtqueue *vq, u32 num)
        vq->in_use = false;
        vq->last_add_time_valid = false;
 #endif
+
+       if (virtqueue_is_in_order(vq)) {
+               vq->free_head = 0;
+               vq->batch_last.id = UINT_MAX;
+       }
I would try to reuse or refactor virtqueue_vring_attach_split() to
reduce code duplication.

Btw have you checked Qemu shadow virtqueue as it might suffer from the
same issue.

Thanks
 }


--
2.9.4

答复: [外部邮件] Re: [PATCH] virtio_ring: reset IN_ORDER state in virtqueue_init()

From: Li,Rongqing <hidden>
Date: 2026-09-11 06:05:38

quoted
The IN_ORDER feature uses additional software state to track the next
available descriptor and in-flight descriptor batches.

virtqueue_init() resets the common virtqueue state, but free_head and
batch_last.id are initialized only when the virtqueue is created. When
an IN_ORDER virtqueue is reset, these fields can retain state from the
previous queue instance.

Reset free_head and invalidate batch_last when initializing an
IN_ORDER virtqueue. Keep this in virtqueue_init() so the state is
initialized consistently for both newly created and reset virtqueues.

Fixes: f6a15d854986 ("virtio_ring: add in order support")
I think this is needed for -stable.
quoted
Signed-off-by: Li RongQing <redacted>
---
 drivers/virtio/virtio_ring.c | 5 +++++
 1 file changed, 5 insertions(+)
diff --git a/drivers/virtio/virtio_ring.c
b/drivers/virtio/virtio_ring.c index db678f5..d0dc464 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -559,6 +559,11 @@ static void virtqueue_init(struct vring_virtqueue *vq,
u32 num)
quoted
        vq->in_use = false;
        vq->last_add_time_valid = false;  #endif
+
+       if (virtqueue_is_in_order(vq)) {
+               vq->free_head = 0;
+               vq->batch_last.id = UINT_MAX;
+       }
I would try to reuse or refactor virtqueue_vring_attach_split() to reduce code
duplication.

Btw have you checked Qemu shadow virtqueue as it might suffer from the same
issue.
I checked QEMU's shadow virtqueue implementation. batch_last is reinitialized in vhost_svq_start(), 
but free_head is not. Since the SVQ object can be reused across stop/start, free_head may retain stale 
state. So a corresponding fix should be needed

void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev,
                      VirtQueue *vq, VhostIOVATree *iova_tree)
 {
     ...
     svq->shadow_avail_idx = 0;
     svq->shadow_used_idx = 0;
+    svq->free_head = 0;
     memset(&svq->batch_last, 0, sizeof(svq->batch_last));
     svq->last_used = 0;
     svq->last_used_idx = 0;

thanks
 
[Li,Rongqing] 

Thanks
quoted
 }


--
2.9.4
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help