> virtblk_read_limits() takes max_segments from the device's seg_max and
> only clamps it to VIRTIO_BLK_MAX_SG_ELEMS - 2, which fits the largest
> virtqueue the spec allows, not the one the device has. Without
> VIRTIO_RING_F_INDIRECT_DESC every segment takes a descriptor in the
> ring, next to the header and the status. A device that offers a seg_max
> above its queue size minus two thus lets the block layer build requests
> that can never be added: virtqueue_add_split() warns that the request
> is larger than the ring and returns -ENOSPC, and the hardware queue is
> stopped to wait for descriptors that even an empty ring does not have.
> The I/O hangs.
> 
> Seen with a device that offers seg_max 254 on a 128-entry queue without
> indirect descriptors, where the boot hangs loading /sbin/init:
> 
>   WARNING: drivers/virtio/virtio_ring.c:688 at virtqueue_add_split+0x6c0/0x850
>   ...
>    virtqueue_add_sgs+0xd1/0x120
>    virtblk_add_req+0xe2/0x140
>    virtio_queue_rq+0x79/0x1a0
> 
> With seg_max 126 it boots, with 127 it hangs.
> 
> Without indirect descriptors, clamp max_segments to the size of the
> smallest virtqueue minus two. The previous commit makes the probe fail
> for a virtqueue smaller than three, so at least one segment is left.
> 
> Assisted-by: Claude:claude-opus-5-5
> Signed-off-by: Stjepan Poljak <[email protected]>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review ยท 
https://sashiko.dev/#/patchset/[email protected]?part=2


Reply via email to