qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v4 2/2] migration: check magic value for deciding the mapping


From: Daniel P . Berrangé
Subject: Re: [PATCH v4 2/2] migration: check magic value for deciding the mapping of channels
Date: Wed, 23 Nov 2022 16:19:20 +0000
User-agent: Mutt/2.2.7 (2022-08-07)

On Wed, Nov 23, 2022 at 09:34:35PM +0530, manish.mishra wrote:
> 
> On 23/11/22 9:28 pm, Daniel P. Berrangé wrote:
> > On Wed, Nov 23, 2022 at 03:05:27PM +0000, manish.mishra wrote:
> > > Current logic assumes that channel connections on the destination side are
> > > always established in the same order as the source and the first one will
> > > always be the main channel followed by the multifid or post-copy
> > > preemption channel. This may not be always true, as even if a channel has 
> > > a
> > > connection established on the source side it can be in the pending state 
> > > on
> > > the destination side and a newer connection can be established first.
> > > Basically causing out of order mapping of channels on the destination 
> > > side.
> > > Currently, all channels except post-copy preempt send a magic number, this
> > > patch uses that magic number to decide the type of channel. This logic is
> > > applicable only for precopy(multifd) live migration, as mentioned, the
> > > post-copy preempt channel does not send any magic number. Also, tls live
> > > migrations already does tls handshake before creating other channels, so
> > > this issue is not possible with tls, hence this logic is avoided for tls
> > > live migrations. This patch uses read peek to check the magic number of
> > > channels so that current data/control stream management remains
> > > un-effected.
> > > 
> > > Reviewed-by: Peter Xu <peterx@redhat.com>
> > > Reviewed-by: Daniel P. Berrangé <berrange@redhat.co
> > > Suggested-by: Daniel P. Berrangé <berrange@redhat.com
> > > Signed-off-by: manish.mishra <manish.mishra@nutanix.com>
> > > ---
> > >   migration/channel.c      | 46 ++++++++++++++++++++++++++++++++++++++++
> > >   migration/channel.h      |  5 +++++
> > >   migration/migration.c    | 45 ++++++++++++++++++++++++++++-----------
> > >   migration/multifd.c      | 12 ++++-------
> > >   migration/multifd.h      |  2 +-
> > >   migration/postcopy-ram.c |  5 +----
> > >   migration/postcopy-ram.h |  2 +-
> > >   7 files changed, 91 insertions(+), 26 deletions(-)
> > > 
> > > diff --git a/migration/channel.c b/migration/channel.c
> > > index 1b0815039f..a4600f52c5 100644
> > > --- a/migration/channel.c
> > > +++ b/migration/channel.c
> > > @@ -92,3 +92,49 @@ void migration_channel_connect(MigrationState *s,
> > >       migrate_fd_connect(s, error);
> > >       error_free(error);
> > >   }
> > > +
> > > +
> > > +/**
> > > + * @migration_channel_read_peek - Read from the peek of migration 
> > > channel,
> > > + *    without actually removing it from channel buffer.
> > > + *
> > > + * @ioc: the channel object
> > > + * @buf: the memory region to read data into
> > > + * @buflen: the number of bytes to read in @buf
> > > + * @errp: pointer to a NULL-initialized error object
> > > + *
> > > + * Returns 0 if successful, returns -1 and sets @errp if fails.
> > > + */
> > > +int migration_channel_read_peek(QIOChannel *ioc,
> > > +                                const char *buf,
> > > +                                const size_t buflen,
> > > +                                Error **errp)
> > > +{
> > > +   ssize_t len = 0;
> > > +   struct iovec iov = { .iov_base = (char *)buf, .iov_len = buflen };
> > > +
> > > +   while (len < buflen) {
> > > +       len = qio_channel_readv_full(ioc, &iov, 1, NULL,
> > > +                                    NULL, 
> > > QIO_CHANNEL_READ_FLAG_MSG_PEEK, errp);
> > > +
> > > +       if (len == QIO_CHANNEL_ERR_BLOCK) {
> > > +            if (qemu_in_coroutine()) {
> > > +                /* 1ms sleep. */
> > > +                qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1000000);
> > > +            } else {
> > > +                qio_channel_wait(ioc, G_IO_IN);
> > > +            }
> > > +            continue;
> > > +       }
> > > +       if (len == 0) {
> > > +           error_setg(errp,
> > > +                      "Unexpected end-of-file on channel");
> > > +           return -1;
> > > +       }
> > > +       if (len < 0) {
> > > +           return -1;
> > > +       }
> > > +   }
> > This busy waits when len > 0 and < buflen
> > 
> > 
> > With regards,
> > Daniel
> 
> Sorry,   Daniel, may be i misunderstood something from earlier
> discussions. I thought we discussed we may not prevent it from
> looping multiple times but we can  qemu_co_sleep_ns after every
> retry to deal with busy wait?

You're only calling  qemu_co_sleep_ns when you get ERR_BLOCK
though. That will happen the first time when 0 bytes are
pending. Once 2 bytes arrive and we're waiting for 2 more,
this code will busy wait instead of calling qemu_co_sleep_ns
again, because len==2 in that case.



With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|




reply via email to

[Prev in Thread] Current Thread [Next in Thread]