On Tue, Nov 30, 2021 at 9:46 PM Stefan Hajnoczi <[email protected]> wrote: > > Packed Virtqueues wrap used_idx instead of letting it run freely like > Split Virtqueues do. If the used ring wraps more than once there is no > way to compare vq->signalled_used and vq->used_idx in > virtio_packed_should_notify() since they are modulo vq->vring.num. > > This causes the device to stop sending used buffer notifications when > when virtio_packed_should_notify() is called less than once each time > around the used ring. > > It is possible to trigger this with virtio-blk's dataplane > notify_guest_bh() irq coalescing optimization. The call to > virtio_notify_irqfd() (and virtio_packed_should_notify()) is deferred to > a BH. If the guest driver is polling it can complete and submit more > requests before the BH executes, causing the used ring to wrap more than > once. The result is that the virtio-blk device ceases to raise > interrupts and I/O hangs. > > Cc: Tiwei Bie <[email protected]> > Cc: Jason Wang <[email protected]> > Cc: Michael S. Tsirkin <[email protected]> > Signed-off-by: Stefan Hajnoczi <[email protected]>
Acked-by: Jason Wang <[email protected]> > --- > Smarter solutions welcome, but I think notifying once per vq->vring.num > is acceptable. > --- > hw/virtio/virtio.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c > index ea7c079fb0..f7851c2750 100644 > --- a/hw/virtio/virtio.c > +++ b/hw/virtio/virtio.c > @@ -885,6 +885,7 @@ static void virtqueue_packed_flush(VirtQueue *vq, > unsigned int count) > if (vq->used_idx >= vq->vring.num) { > vq->used_idx -= vq->vring.num; > vq->used_wrap_counter ^= 1; > + vq->signalled_used_valid = false; > } > } > > -- > 2.33.1 >
