All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Peter Xu <peterx@redhat.com>
Cc: qemu-devel@nongnu.org, Fabiano Rosas <farosas@suse.de>,
	Juraj Marcin <jmarcin@redhat.com>, Feifan Qian <bea1e@proton.me>
Subject: Re: [PATCH 4/5] migration: Fix rare hang of migration_channel_read_peek()
Date: Tue, 28 Jul 2026 17:24:36 +0100	[thread overview]
Message-ID: <amjXxDH73ah-dUGE@redhat.com> (raw)
In-Reply-To: <20260728155247.1894355-5-peterx@redhat.com>

On Tue, Jul 28, 2026 at 11:52:46AM -0400, Peter Xu wrote:
> In an unlikely case, when a migration stream is attached to the destination
> QEMU and only send <4 bytes to the channel as magic, it's possible that
> migration_channel_read_peek() may spin forever without yielding in the main
> thread causing two unwanted consequences:
> 
> - CPU will spin 100% waiting for the rest bytes until it reaches 4
> - (more importantly..) Main thread is stuck during this process as the qio
>   operation won't really yield the coroutine
> 
> Fix it by consuming the bytes that arrived.
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3889
> Cc: Daniel P. Berrangé <berrange@redhat.com>
> Reported-by: Feifan Qian <bea1e@proton.me>
> Signed-off-by: Peter Xu <peterx@redhat.com>
> ---
>  migration/channel.c | 26 +++++++++++++++++++++++---
>  1 file changed, 23 insertions(+), 3 deletions(-)
> 
> diff --git a/migration/channel.c b/migration/channel.c
> index 1e2935f926..28fe1d2906 100644
> --- a/migration/channel.c
> +++ b/migration/channel.c
> @@ -294,11 +294,31 @@ int migration_channel_read_peek(QIOChannel *ioc,
>              return -1;
>          }
>  
> -        if (len == buflen) {
> +        if (len == iov.iov_len) {
>              break;
> -        }
> +        } else if (len == 0) {
> +            qio_channel_wait_cond(ioc, G_IO_IN);
> +        } else {
> +            ssize_t received = len;
>  
> -        qio_channel_wait_cond(ioc, G_IO_IN);
> +            /*
> +             * Partially arrived, read out to make qio_channel_wait_cond()
> +             * won't return immediately, causing an unwanted spin on this
> +             * CPU.
> +             */
> +            iov.iov_len = len;
> +            len = qio_channel_readv_full(ioc, &iov, 1, NULL, NULL, 0, errp);

Sure this breaks the API behaviour that the caller is expecting to
see.

migration_channel_identify will call migration_channel_read_peek
to match the magic bytes.

But something later in the flow will actually try to read the magic
bytes.  By consuming them in this migration_channel_read_peek
method, surely we're breaking the code that wants to read the bytes
later.

> +            /*
> +             * QIO_CHANNEL_ERR_BLOCK also shouldn't happen, due to the
> +             * prior peek just happened.  We should be pretty sure we will
> +             * read what we peeked, or the channel was broken.
> +             */
> +            if (len != received) {
> +                return -1;
> +            }
> +            iov.iov_base += received;
> +            iov.iov_len = buflen - received;
> +        }
>      }
>  
>      return 0;
> -- 
> 2.54.0
> 

With regards,
Daniel
-- 
|: https://berrange.com       ~~        https://hachyderm.io/@berrange :|
|: https://libvirt.org          ~~          https://entangle-photo.org :|
|: https://pixelfed.art/berrange   ~~    https://fstop138.berrange.com :|



  reply	other threads:[~2026-07-28 16:25 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-28 15:52 [PATCH 0/5] migration: Hardening fixes for 11.2 Peter Xu
2026-07-28 15:52 ` [PATCH 1/5] migration: Fix possible overflow in vmstate_handle_alloc() Peter Xu
2026-07-28 19:19   ` Fabiano Rosas
2026-07-28 15:52 ` [PATCH 2/5] migration/multifd: Validate next_packet_size in zlib/zstd recv Peter Xu
2026-07-28 19:44   ` Fabiano Rosas
2026-07-28 15:52 ` [PATCH 3/5] migration/multifd: Replace assert() with error_setg() in recv paths Peter Xu
2026-07-28 19:51   ` Fabiano Rosas
2026-07-28 20:28     ` Peter Xu
2026-07-28 20:59       ` Fabiano Rosas
2026-07-28 21:07         ` Peter Xu
2026-07-28 15:52 ` [PATCH 4/5] migration: Fix rare hang of migration_channel_read_peek() Peter Xu
2026-07-28 16:24   ` Daniel P. Berrangé [this message]
2026-07-28 17:09     ` Peter Xu
2026-07-28 17:12       ` Daniel P. Berrangé
2026-07-28 19:59       ` Fabiano Rosas
2026-07-28 20:46         ` Peter Xu
2026-07-28 21:00           ` Fabiano Rosas
2026-07-28 21:31             ` Peter Xu
2026-07-28 15:52 ` [PATCH 5/5] migration/ram: Check for RAMBlock size mismatch when parsing Peter Xu
2026-07-28 19:54   ` Fabiano Rosas

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=amjXxDH73ah-dUGE@redhat.com \
    --to=berrange@redhat.com \
    --cc=bea1e@proton.me \
    --cc=farosas@suse.de \
    --cc=jmarcin@redhat.com \
    --cc=peterx@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /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.