[Devel] [PATCH 4/4] virtio_balloon: warn on failed buffer add to a broken queue #VSTOR-135654
Denis V. Lunev
den at openvz.org
Mon Jun 29 15:34:56 MSK 2026
tell_host() and stats_handle_request() both ignore the return value of
virtqueue_add_outbuf() and go on to kick the queue. The comment claims
"We should always be able to add one buffer to an empty queue", but that
does not hold once the virtqueue has been broken (e.g. on device
shutdown), where the add fails with -EIO.
In tell_host() the following wait_event() would then block forever on a
buffer the host can never return. stats_handle_request() does not
wait_event() afterwards so it cannot hang, but it still kicks a queue
with nothing queued.
Warn and bail out on failure in both, mirroring
virtballoon_free_page_report().
Suggested-by: David Hildenbrand <david at kernel.org>
Signed-off-by: Denis V. Lunev <den at openvz.org>
---
drivers/virtio/virtio_balloon.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index d6106ccecf71..56c652555663 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -185,16 +185,18 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq)
{
struct scatterlist sg;
unsigned int len;
+ int err;
sg_init_one(&sg, vb->pfns, sizeof(vb->pfns[0]) * vb->num_pfns);
/* We should always be able to add one buffer to an empty queue. */
- virtqueue_add_outbuf(vq, &sg, 1, vb, GFP_KERNEL);
+ err = virtqueue_add_outbuf(vq, &sg, 1, vb, GFP_KERNEL);
+ if (WARN_ON_ONCE(err))
+ return;
virtqueue_kick(vq);
/* When host has read buffer, this completes via balloon_ack */
wait_event(vb->acked, virtqueue_get_buf(vq, &len));
-
}
static int virtballoon_free_page_report(struct page_reporting_dev_info *pr_dev_info,
@@ -449,6 +451,7 @@ static void stats_handle_request(struct virtio_balloon *vb)
struct virtqueue *vq;
struct scatterlist sg;
unsigned int len, num_stats;
+ int err;
num_stats = update_balloon_stats(vb);
@@ -456,7 +459,9 @@ static void stats_handle_request(struct virtio_balloon *vb)
if (!virtqueue_get_buf(vq, &len))
return;
sg_init_one(&sg, vb->stats, sizeof(vb->stats[0]) * num_stats);
- virtqueue_add_outbuf(vq, &sg, 1, vb, GFP_KERNEL);
+ err = virtqueue_add_outbuf(vq, &sg, 1, vb, GFP_KERNEL);
+ if (WARN_ON_ONCE(err))
+ return;
virtqueue_kick(vq);
}
--
2.53.0
More information about the Devel
mailing list