From: "Michael S. Tsirkin" <mst@redhat.com>
To: "David Hildenbrand (Arm)" <david@kernel.org>
Cc: linux-kernel@vger.kernel.org, "Jason Wang" <jasowang@redhat.com>,
"Xuan Zhuo" <xuanzhuo@linux.alibaba.com>,
"Eugenio Pérez" <eperezma@redhat.com>,
"Adam Litke" <agl@us.ibm.com>,
"Rusty Russell" <rusty@rustcorp.com.au>,
virtualization@lists.linux.dev,
"Andrew Morton" <akpm@linux-foundation.org>,
linux-mm@kvack.org
Subject: Re: [PATCH v2] virtio_balloon: prime stats vq after virtio_device_ready()
Date: Mon, 6 Jul 2026 04:23:46 -0400 [thread overview]
Message-ID: <20260706042207-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <13794c5e-375a-4fc5-84b4-a637d077f8a0@kernel.org>
On Mon, Jul 06, 2026 at 09:28:50AM +0200, David Hildenbrand (Arm) wrote:
> On 7/5/26 21:12, Michael S. Tsirkin wrote:
> > The virtio spec requires the driver not to kick the device before
> > DRIVER_OK is set. init_vqs() primes the stats virtqueue with a buffer
> > and kicks the device before virtio_device_ready() is called in
> > virtballoon_probe(), violating this requirement.
> >
> > Further, if the device responds to the early kick by processing the
> > buffer before DRIVER_OK, stats_request() fires and queues
> > update_balloon_stats_work. Should probe then fail and free vb, the work
> > runs against freed memory.
> >
> > To fix, move buffer setup to after DRIVER_OK. Be careful to
> > disable update_balloon_stats_work while this is going on,
> > to make sure it does not race with the setup.
> >
> > setup_vqs() warns but does not fail probe or restore if
> > virtqueue_add_outbuf() fails; the call never actually fails in these
> > contexts since the queue is freshly initialized and empty.
> >
> > Testing: tested that stats still work after the change.
> >
> > Fixes: 9564e138b1f6 ("virtio: Add memory statistics reporting to the balloon driver (V4)")
> > Reported-by: Sashiko:gemini-3.1-pro-preview
> > Cc: David Hildenbrand <david@kernel.org>
> > Assisted-by: Claude:claude-sonnet-4-6
> > Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> > ---
> >
> > changes from v1:
> > check that work enable/disable is balanced
> > explain how add buf never fails in probe/restore
> >
> > drivers/virtio/virtio_balloon.c | 50 +++++++++++++++++++++------------
> > 1 file changed, 32 insertions(+), 18 deletions(-)
> >
> > diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
> > index 088b3a0e6ce6..bc0a2b19ca7d 100644
> > --- a/drivers/virtio/virtio_balloon.c
> > +++ b/drivers/virtio/virtio_balloon.c
> > @@ -611,25 +611,8 @@ static int init_vqs(struct virtio_balloon *vb)
> > vb->inflate_vq = vqs[VIRTIO_BALLOON_VQ_INFLATE];
> > vb->deflate_vq = vqs[VIRTIO_BALLOON_VQ_DEFLATE];
> > if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ)) {
> > - struct scatterlist sg;
> > - unsigned int num_stats;
> > vb->stats_vq = vqs[VIRTIO_BALLOON_VQ_STATS];
> > -
> > - /*
> > - * Prime this virtqueue with one buffer so the hypervisor can
> > - * use it to signal us later (it can't be broken yet!).
> > - */
> > - num_stats = update_balloon_stats(vb);
> > -
> > - sg_init_one(&sg, vb->stats, sizeof(vb->stats[0]) * num_stats);
> > - err = virtqueue_add_outbuf(vb->stats_vq, &sg, 1, vb,
> > - GFP_KERNEL);
> > - if (err) {
> > - dev_warn(&vb->vdev->dev, "%s: add stat_vq failed\n",
> > - __func__);
> > - return err;
> > - }
> > - virtqueue_kick(vb->stats_vq);
> > + disable_work(&vb->update_balloon_stats_work);
>
> That's to stop the stats queue triggering stats_request() I assume?
Yes.
> Is that
> valid before we actually added+kicked ourselves?
Why not?
> Also, can't we simply handle that in stats_request(), just ignoring it there?
Then we'd need to maintain a special flag and I dislike that.
> Then we wouldn't have to go through the siable + enable.
We'd still need to flip the flag on/off.
> > }
> >
> > if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT))
> > @@ -916,6 +899,33 @@ static int virtio_balloon_register_shrinker(struct virtio_balloon *vb)
> > return 0;
> > }
> >
> > +static void setup_vqs(struct virtio_balloon *vb)
> > +{
> > + struct scatterlist sg;
> > + unsigned int num_stats;
> > + bool ret;
> > +
> > + if (!virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ))
> > + return;
> > +
> > + /*
> > + * Prime this virtqueue with one buffer so the hypervisor can
> > + * use it to signal us later (it can't be broken yet!).
> > + */
> > + num_stats = update_balloon_stats(vb);
> > + sg_init_one(&sg, vb->stats, sizeof(vb->stats[0]) * num_stats);
> > + if (virtqueue_add_outbuf(vb->stats_vq, &sg, 1, vb, GFP_KERNEL)) {
> > + dev_warn(&vb->vdev->dev, "%s: add stat_vq failed\n", __func__);
> > + return;
> > + }
> > + virtqueue_kick(vb->stats_vq);
> > +
> > + ret = enable_and_queue_work(system_freezable_wq,
> > + &vb->update_balloon_stats_work);
> > + /* Make sure we balanced enable/disable, or we won't report stats. */
> > + BUG_ON(!ret);
>
> A WARN_ON_ONCE() should be good enough here, no need to crash the kernel (no new
> BUG_ON's).
Will do, thanks!
> --
> Cheers,
>
> David
next prev parent reply other threads:[~2026-07-06 8:23 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-05 19:12 [PATCH v2] virtio_balloon: prime stats vq after virtio_device_ready() Michael S. Tsirkin
2026-07-06 7:28 ` David Hildenbrand (Arm)
2026-07-06 8:23 ` Michael S. Tsirkin [this message]
2026-07-06 8:38 ` David Hildenbrand (Arm)
2026-07-06 8:43 ` Michael S. Tsirkin
2026-07-06 8:57 ` David Hildenbrand (Arm)
2026-07-06 12:59 ` Michael S. Tsirkin
2026-07-06 13:42 ` David Hildenbrand (Arm)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260706042207-mutt-send-email-mst@kernel.org \
--to=mst@redhat.com \
--cc=agl@us.ibm.com \
--cc=akpm@linux-foundation.org \
--cc=david@kernel.org \
--cc=eperezma@redhat.com \
--cc=jasowang@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=rusty@rustcorp.com.au \
--cc=virtualization@lists.linux.dev \
--cc=xuanzhuo@linux.alibaba.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.