qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Peter Xu <peterx@redhat.com>
To: Marco Cavenati <Marco.Cavenati@eurecom.fr>
Cc: qemu-devel@nongnu.org, farosas@suse.de, ppandit@redhat.com,
	berrange@redhat.com
Subject: Re: [PATCH 3/3] migration: mapped-ram: handle zero pages
Date: Tue, 7 Oct 2025 17:11:18 -0400	[thread overview]
Message-ID: <aOWB9oxknXYjeY-i@x1.local> (raw)
In-Reply-To: <26083e-68de3c80-5f3-4691f480@28926673>

On Thu, Oct 02, 2025 at 10:49:45AM +0200, Marco Cavenati wrote:
> Please note that there are a couple of errors (swapped parameters), which are
> detailed below.
> I will address these in the next iteration, along with any additional changes
> based on your feedback.
> 
> Thank you
> Marco
> 
> On Wednesday, October 01, 2025 18:18 CEST, Marco Cavenati <Marco.Cavenati@eurecom.fr> wrote:
> 
> > Make mapped-ram compatible with loadvm snapshot restoring by explicitly
> > zeroing memory pages in this case.
> > Skip zeroing for -incoming and -loadvm migrations to preserve performance.
> > 
> > Signed-off-by: Marco Cavenati <Marco.Cavenati@eurecom.fr>
> > ---
> >  migration/ram.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 55 insertions(+), 1 deletion(-)
> > 
> > diff --git a/migration/ram.c b/migration/ram.c
> > index e238c9233f..597d5ffe9e 100644
> > --- a/migration/ram.c
> > +++ b/migration/ram.c
> > @@ -3958,12 +3958,55 @@ static size_t ram_load_multifd_pages(void *host_addr, size_t size,
> >      return size;
> >  }
> >  
> > +/**
> > + * handle_zero_mapped_ram: Zero out a range of RAM pages if required during
> > + * mapped-ram load
> > + *
> > + * Zeroing is only performed when restoring from a snapshot (HMP loadvm).
> > + * During incoming migration or -loadvm cli snapshot load, the function is a
> > + * no-op and returns true as in those cases the pages are already guaranteed to
> > + * be zeroed.
> > + *
> > + * Returns: true on success, false on error (with @errp set).
> > + * @from_bit_idx: Starting index relative to the map of the page (inclusive)
> > + * @to_bit_idx:   Ending index relative to the map of the page (exclusive)
> > + */
> > +static bool handle_zero_mapped_ram(RAMBlock *block, unsigned long from_bit_idx,
> > +                                   unsigned long to_bit_idx, Error **errp)
> > +{
> > +    ERRP_GUARD();
> > +    ram_addr_t offset;
> > +    size_t size;
> > +    void *host;
> > +
> > +    if (runstate_check(RUN_STATE_INMIGRATE) ||
> > +        runstate_check(RUN_STATE_PRELAUNCH)) {

Should we check RUN_STATE_RESTORE_VM directly here?

I think it's still good to spell out the rest, we could put it in a
comment, e.g.:

  /*
   * Zeroing is not needed for either -loadvm (RUN_STATE_PRELAUNCH), or
   * -incoming (RUN_STATE_INMIGRATE).
   */

> > +        return true;
> > +    }
> > +
> > +    if (from_bit_idx == to_bit_idx) {

Might be safer to check >= rather than ==.

> > +        return true;
> > +    }
> > +
> > +    size = TARGET_PAGE_SIZE * (to_bit_idx - from_bit_idx);
> > +    offset = from_bit_idx << TARGET_PAGE_BITS;
> > +    host = host_from_ram_block_offset(block, offset);
> > +    if (!host) {
> > +        error_setg(errp, "zero page outside of ramblock %s range",
> > +                   block->idstr);
> > +        return false;
> > +    }
> > +    ram_handle_zero(host, size);
> > +
> > +    return true;
> > +}
> > +
> >  static bool read_ramblock_mapped_ram(QEMUFile *f, RAMBlock *block,
> >                                       long num_pages, unsigned long *bitmap,
> >                                       Error **errp)
> >  {
> >      ERRP_GUARD();
> > -    unsigned long set_bit_idx, clear_bit_idx;
> > +    unsigned long set_bit_idx, clear_bit_idx = 0;
> >      ram_addr_t offset;
> >      void *host;
> >      size_t read, unread, size;
> > @@ -3972,6 +4015,12 @@ static bool read_ramblock_mapped_ram(QEMUFile *f, RAMBlock *block,
> >           set_bit_idx < num_pages;
> >           set_bit_idx = find_next_bit(bitmap, num_pages, clear_bit_idx + 1)) {
> >  
> > +        /* Zero pages */
> > +        if (!handle_zero_mapped_ram(block, set_bit_idx, clear_bit_idx, errp)) {
> 
> This should be
> +         if (!handle_zero_mapped_ram(block, clear_bit_idx, set_bit_idx, errp)) {
> 
> > +            return false;
> > +        }
> > +
> > +        /* Non-zero pages */
> >          clear_bit_idx = find_next_zero_bit(bitmap, num_pages, set_bit_idx + 1);
> >  
> >          unread = TARGET_PAGE_SIZE * (clear_bit_idx - set_bit_idx);
> > @@ -4003,6 +4052,11 @@ static bool read_ramblock_mapped_ram(QEMUFile *f, RAMBlock *block,
> >          }
> >      }
> >  
> > +    /* Handle trailing 0 pages */
> > +    if (!handle_zero_mapped_ram(block, num_pages, clear_bit_idx, errp)) {
> 
> This should be
> +    if (!handle_zero_mapped_ram(block, clear_bit_idx, num_pages, errp)) {

The rest looks all good.

I can queue patch 2 now, which is trivial.  Please repost patch 1+3 after
rebasing to Fabiano's patch here:

https://lore.kernel.org/r/20251007184213.5990-1-farosas@suse.de

Then in patch 3 you can remove the MAPPED_RAM cap in the list.

Fabiano could also be posting some test patches too that he got for
snapshots.  You can either respin before that, or wait for it (then you can
also add a mapped-ram test for snapshots).

Thanks,

-- 
Peter Xu



  reply	other threads:[~2025-10-07 21:12 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-01 16:18 [PATCH 0/3] migration: Add support for mapped-ram with snapshots Marco Cavenati
2025-10-01 16:18 ` [PATCH 1/3] migration: add FEATURE_SEEKABLE to QIOChannelBlock Marco Cavenati
2025-10-02 14:45   ` Juraj Marcin
2025-10-03  9:47     ` Marco Cavenati
2025-10-01 16:18 ` [PATCH 2/3] migration/ram: fix docs of ram_handle_zero Marco Cavenati
2025-10-02 14:48   ` Juraj Marcin
2025-10-01 16:18 ` [PATCH 3/3] migration: mapped-ram: handle zero pages Marco Cavenati
2025-10-02  8:49   ` Marco Cavenati
2025-10-07 21:11     ` Peter Xu [this message]
2025-10-08  9:36       ` Marco Cavenati

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=aOWB9oxknXYjeY-i@x1.local \
    --to=peterx@redhat.com \
    --cc=Marco.Cavenati@eurecom.fr \
    --cc=berrange@redhat.com \
    --cc=farosas@suse.de \
    --cc=ppandit@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).