All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH kvmtool] virtio: 9p: Order used ring updates before notifications
@ 2026-07-24  9:10 Xie Bo
  2026-07-31 17:08 ` Will Deacon
  0 siblings, 1 reply; 2+ messages in thread
From: Xie Bo @ 2026-07-24  9:10 UTC (permalink / raw)
  To: kvm; +Cc: Xie Bo, Will Deacon, Julien Thierry, Anup Patel

virtio_p9_do_io() signals the guest immediately after adding each
request to the used ring. Unlike the block and net backends, it bypasses
virtio_queue__should_signal(), which provides the full memory barrier
needed between publishing used->idx and injecting the interrupt.

On weakly ordered architectures, the guest can therefore handle the
interrupt before the updated used->idx becomes visible. If it observes
the old index and goes back to sleep, the completed request can remain
stuck indefinitely because no further interrupt is generated.

This was observed on RISC-V with two 9p RPCs blocked while the host
used->idx was two entries ahead of the guest's last_used_idx.

Process all available requests first, then use
virtio_queue__should_signal() before notifying the guest. Besides
providing the required ordering, this also honors the driver's
notification suppression request.

Fixes: 1c7850f95903 ("kvm tools: Add virtio-9p")
Signed-off-by: Xie Bo <xb@ultrarisc.com>
---
 virtio/9p.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/virtio/9p.c b/virtio/9p.c
index cf3e547..d2680e9 100644
--- a/virtio/9p.c
+++ b/virtio/9p.c
@@ -1372,11 +1372,15 @@ static void virtio_p9_do_io(struct kvm *kvm, void *param)
 	struct p9_dev_job *job = (struct p9_dev_job *)param;
 	struct p9_dev *p9dev   = job->p9dev;
 	struct virt_queue *vq  = job->vq;
+	bool completed = false;
 
 	while (virt_queue__available(vq)) {
 		virtio_p9_do_io_request(kvm, job);
-		p9dev->vdev.ops->signal_vq(kvm, &p9dev->vdev, vq - p9dev->vqs);
+		completed = true;
 	}
+
+	if (completed && virtio_queue__should_signal(vq))
+		p9dev->vdev.ops->signal_vq(kvm, &p9dev->vdev, vq - p9dev->vqs);
 }
 
 static u8 *get_config(struct kvm *kvm, void *dev)
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH kvmtool] virtio: 9p: Order used ring updates before notifications
  2026-07-24  9:10 [PATCH kvmtool] virtio: 9p: Order used ring updates before notifications Xie Bo
@ 2026-07-31 17:08 ` Will Deacon
  0 siblings, 0 replies; 2+ messages in thread
From: Will Deacon @ 2026-07-31 17:08 UTC (permalink / raw)
  To: Xie Bo; +Cc: kvm, Julien Thierry, Anup Patel

On Fri, Jul 24, 2026 at 05:10:41PM +0800, Xie Bo wrote:
> virtio_p9_do_io() signals the guest immediately after adding each
> request to the used ring. Unlike the block and net backends, it bypasses
> virtio_queue__should_signal(), which provides the full memory barrier
> needed between publishing used->idx and injecting the interrupt.
> 
> On weakly ordered architectures, the guest can therefore handle the
> interrupt before the updated used->idx becomes visible. If it observes
> the old index and goes back to sleep, the completed request can remain
> stuck indefinitely because no further interrupt is generated.
> 
> This was observed on RISC-V with two 9p RPCs blocked while the host
> used->idx was two entries ahead of the guest's last_used_idx.
> 
> Process all available requests first, then use
> virtio_queue__should_signal() before notifying the guest. Besides
> providing the required ordering, this also honors the driver's
> notification suppression request.
> 
> Fixes: 1c7850f95903 ("kvm tools: Add virtio-9p")
> Signed-off-by: Xie Bo <xb@ultrarisc.com>
> ---
>  virtio/9p.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/virtio/9p.c b/virtio/9p.c
> index cf3e547..d2680e9 100644
> --- a/virtio/9p.c
> +++ b/virtio/9p.c
> @@ -1372,11 +1372,15 @@ static void virtio_p9_do_io(struct kvm *kvm, void *param)
>  	struct p9_dev_job *job = (struct p9_dev_job *)param;
>  	struct p9_dev *p9dev   = job->p9dev;
>  	struct virt_queue *vq  = job->vq;
> +	bool completed = false;
>  
>  	while (virt_queue__available(vq)) {
>  		virtio_p9_do_io_request(kvm, job);
> -		p9dev->vdev.ops->signal_vq(kvm, &p9dev->vdev, vq - p9dev->vqs);
> +		completed = true;
>  	}
> +
> +	if (completed && virtio_queue__should_signal(vq))
> +		p9dev->vdev.ops->signal_vq(kvm, &p9dev->vdev, vq - p9dev->vqs);

Why do you need the 'completed' bool here? Can't we just rely on
virtio_queue__should_signal() instead?

Will

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-07-31 17:08 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-24  9:10 [PATCH kvmtool] virtio: 9p: Order used ring updates before notifications Xie Bo
2026-07-31 17:08 ` Will Deacon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.