On Mon, 17 Aug 2026 at 09:47, Christoph Hellwig <[email protected]> wrote: > > On Fri, Aug 14, 2026 at 12:59:54PM +0200, Sergii Ushakov wrote: > > When VIRTIO_RING_F_INDIRECT_DESC is not negotiated by the host, every > > scatter-gather segment in a request must consume a physical slot in > > the virtqueue ring. > > > > If the host does not advertise VIRTIO_BLK_F_SEG_MAX and provides a small > > virtqueue (e.g. 128 descriptors on QNX Hypervisor), the block layer > > defaults max_segments to BLK_MAX_SEGMENTS (1024). When a multi-page > > compound bio arrives from the page cache, virtqueue_add_split() rejects > > the request with -ENOSPC and triggers: > > > > WARNING: at drivers/virtio/virtio_ring.c:1493 virtqueue_add+... > > WARN_ON_ONCE(total_sg > vq->split.vring.num && !vq->indirect); > > > > This permanently wedges the blk-mq queue and blocks all subsequent disk > > I/O in uninterruptible sleep (D state). > > > > Add a virtio_blk.max_segments module parameter to allow runtime cmdline > > overrides, and automatically clamp sg_elems to > > (virtqueue_get_vring_size - 2) when indirect descriptors are disabled. > > What is the reason for the override?
The module parameter was intended for two main reasons: 1. A safety fallback for non-compliant/buggy hypervisors that may have internal segment limits lower than the advertised ring size without advertising VIRTIO_BLK_F_SEG_MAX. 2. Debugging and performance benchmarking of smaller scatter-gather lists without needing kernel rebuilds. That said, the automatic clamping to (vring_size - 2) resolves the hang and panic out-of-the-box. If the preference is to avoid adding a new module parameter, we may drop it and keep only the automatic clamping.

