[Devel] [PATCH v3 VZ10 1/1] vhost-blk: fix in-flight request counter leakage
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Tue Jun 2 16:43:43 MSK 2026
On 6/2/26 11:38, Andrey Drobyshev wrote:
> Upon request completion, vhost_blk_handle_host_kick() pops the request from
> the queue and writes one status byte into the guest's status iov via
> vhost_blk_set_status().
>
> If for whatever reason vhost_blk_set_status() fails (e.g. virtio device
> reset/disable on that queue, or QEMU-driven device state changes like
> block_resize) - we end up forgetting to call forget_request() and
> decrease the in-flight counter. Thus it remains > 0 forever.
>
> Later upon guest shutdown, when flush happens, we end up forever waiting
> in D state in vhost_blk_flush() on this operation:
>
> wait_event(blk->flush_wait, !atomic_read(&blk->req_inflight[flush_bin]));
>
> So that even SIGKILL can't reap the QEMU process. That's exactly what
> we observed in hci-volumes test after block_resize.
>
> Fix by adjusting the loop body so that forget_request() is always called
> unconditionally.
>
> https://virtuozzo.atlassian.net/browse/VSTOR-132571
> Fixes: 40a5928ec730 ("drivers/vhost: vhost-blk accelerator for virtio-blk guests")
> Signed-off-by: Andrey Drobyshev <andrey.drobyshev at virtuozzo.com>
Reviewed-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
> ---
> v2 -> v3:
> * Suppress possible return value for vhost_blk_set_status().
>
> v1 -> v2:
> * Don't skip calling vhost_add_used(). Just remove if(...) clause and
> call vhost_blk_set_status(), vhost_add_used() and forget_request()
> unconditionally.
>
> drivers/vhost/blk.c | 5 +----
> 1 file changed, 1 insertion(+), 4 deletions(-)
>
> diff --git a/drivers/vhost/blk.c b/drivers/vhost/blk.c
> index f8bedc3e0ee8..996bde9f546c 100644
> --- a/drivers/vhost/blk.c
> +++ b/drivers/vhost/blk.c
> @@ -565,7 +565,6 @@ static void vhost_blk_handle_host_kick(struct vhost_work *work)
> struct vhost_blk *blk = NULL;
> bool added;
> u8 status;
> - int ret;
>
> blk_vq = container_of(work, struct vhost_blk_vq, work);
> vq = &blk_vq->vq;
> @@ -585,9 +584,7 @@ static void vhost_blk_handle_host_kick(struct vhost_work *work)
> vhost_blk_req_cleanup(req);
>
> status = req->bio_err == 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR;
> - ret = vhost_blk_set_status(req, status);
> - if (unlikely(ret))
> - continue;
> + (void) vhost_blk_set_status(req, status);
>
> vhost_add_used(vq, req->head, req->len);
> added = true;
--
Best regards, Pavel Tikhomirov
Senior Software Developer, Virtuozzo.
More information about the Devel
mailing list