aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2025-11-04 14:27:33 +0000
committerMark Johnston <markj@FreeBSD.org>2025-11-04 14:35:31 +0000
commitf999ffdce3813eb946f10999ccffb8275c324469 (patch)
treed66f227ae704e3d7258fc5266be43ed9e438adc7
parentc46e5dc65ba5c9666bb4452878e332dc49730843 (diff)
virtio: Fix polling in virtqueue_dequeue()
The access of vq->vq_ring.used->idx needs to be volatile-qualified, otherwise the compiler may optimize virtqueue_poll() into an infinite loop if there is no data available upon the first poll. Prior to commit ad17789a8569 this wasn't a problem since an external function call after each poll inhibited the optimization. PR: 289930 MFC after: 3 days Sponsored by: Klara, Inc. Fixes: ad17789a8569 ("virtio: Remove the unused poll method")
-rw-r--r--sys/dev/virtio/virtqueue.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/sys/dev/virtio/virtqueue.c b/sys/dev/virtio/virtqueue.c
index cc7a233d60ee..41e01549c8b2 100644
--- a/sys/dev/virtio/virtqueue.c
+++ b/sys/dev/virtio/virtqueue.c
@@ -580,7 +580,8 @@ virtqueue_dequeue(struct virtqueue *vq, uint32_t *len)
void *cookie;
uint16_t used_idx, desc_idx;
- if (vq->vq_used_cons_idx == vq_htog16(vq, vq->vq_ring.used->idx))
+ if (vq->vq_used_cons_idx ==
+ vq_htog16(vq, atomic_load_16(&vq->vq_ring.used->idx)))
return (NULL);
used_idx = vq->vq_used_cons_idx++ & (vq->vq_nentries - 1);