Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 1acfe2c

Browse files
Yuan Yaomstsirkin
authored andcommitted
virtio_ring: fix avail_wrap_counter in virtqueue_add_packed
In current packed virtqueue implementation, the avail_wrap_counter won't flip, in the case when the driver supplies a descriptor chain with a length equals to the queue size; total_sg == vq->packed.vring.num. Let’s assume the following situation: vq->packed.vring.num=4 vq->packed.next_avail_idx: 1 vq->packed.avail_wrap_counter: 0 Then the driver adds a descriptor chain containing 4 descriptors. We expect the following result with avail_wrap_counter flipped: vq->packed.next_avail_idx: 1 vq->packed.avail_wrap_counter: 1 But, the current implementation gives the following result: vq->packed.next_avail_idx: 1 vq->packed.avail_wrap_counter: 0 To reproduce the bug, you can set a packed queue size as small as possible, so that the driver is more likely to provide a descriptor chain with a length equal to the packed queue size. For example, in qemu run following commands: sudo qemu-system-x86_64 \ -enable-kvm \ -nographic \ -kernel "path/to/kernel_image" \ -m 1G \ -drive file="path/to/rootfs",if=none,id=disk \ -device virtio-blk,drive=disk \ -drive file="path/to/disk_image",if=none,id=rwdisk \ -device virtio-blk,drive=rwdisk,packed=on,queue-size=4,\ indirect_desc=off \ -append "console=ttyS0 root=/dev/vda rw init=/bin/bash" Inside the VM, create a directory and mount the rwdisk device on it. The rwdisk will hang and mount operation will not complete. This commit fixes the wrap counter error by flipping the packed.avail_wrap_counter, when start of descriptor chain equals to the end of descriptor chain (head == i). Fixes: 1ce9e60 ("virtio_ring: introduce packed ring support") Signed-off-by: Yuan Yao <[email protected]> Message-Id: <[email protected]> Acked-by: Jason Wang <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]>
1 parent ae15ace commit 1acfe2c

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

drivers/virtio/virtio_ring.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1499,7 +1499,7 @@ static inline int virtqueue_add_packed(struct virtqueue *_vq,
14991499
}
15001500
}
15011501

1502-
if (i < head)
1502+
if (i <= head)
15031503
vq->packed.avail_wrap_counter ^= 1;
15041504

15051505
/* We're using some buffers from the free list. */

0 commit comments

Comments
 (0)