qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Peter Xu <peterx@redhat.com>
To: Fabiano Rosas <farosas@suse.de>
Cc: qemu-devel@nongnu.org, berrange@redhat.com, armbru@redhat.com,
	Claudio Fontana <cfontana@suse.de>,
	Eric Blake <eblake@redhat.com>
Subject: Re: [PATCH v4 11/34] migration/ram: Introduce 'fixed-ram' migration capability
Date: Mon, 26 Feb 2024 11:07:25 +0800	[thread overview]
Message-ID: <ZdwAbW3sHZin-gV0@x1n> (raw)
In-Reply-To: <20240220224138.24759-12-farosas@suse.de>

On Tue, Feb 20, 2024 at 07:41:15PM -0300, Fabiano Rosas wrote:
> Add a new migration capability 'fixed-ram'.
> 
> The core of the feature is to ensure that each RAM page has a specific
> offset in the resulting migration stream. The reasons why we'd want
> such behavior are:
> 
>  - The resulting file will have a bounded size, since pages which are
>    dirtied multiple times will always go to a fixed location in the
>    file, rather than constantly being added to a sequential
>    stream. This eliminates cases where a VM with, say, 1G of RAM can
>    result in a migration file that's 10s of GBs, provided that the
>    workload constantly redirties memory.
> 
>  - It paves the way to implement O_DIRECT-enabled save/restore of the
>    migration stream as the pages are ensured to be written at aligned
>    offsets.
> 
>  - It allows the usage of multifd so we can write RAM pages to the
>    migration file in parallel.
> 
> For now, enabling the capability has no effect. The next couple of
> patches implement the core functionality.
> 
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> - update migration.json to 9.0 and improve wording
> - move docs to a separate file and add use cases information
> ---
>  docs/devel/migration/features.rst  |   1 +
>  docs/devel/migration/fixed-ram.rst | 137 +++++++++++++++++++++++++++++
>  migration/options.c                |  34 +++++++
>  migration/options.h                |   1 +
>  migration/savevm.c                 |   1 +
>  qapi/migration.json                |   6 +-
>  6 files changed, 179 insertions(+), 1 deletion(-)
>  create mode 100644 docs/devel/migration/fixed-ram.rst
> 
> diff --git a/docs/devel/migration/features.rst b/docs/devel/migration/features.rst
> index a9acaf618e..4c708b679a 100644
> --- a/docs/devel/migration/features.rst
> +++ b/docs/devel/migration/features.rst
> @@ -10,3 +10,4 @@ Migration has plenty of features to support different use cases.
>     dirty-limit
>     vfio
>     virtio
> +   fixed-ram
> diff --git a/docs/devel/migration/fixed-ram.rst b/docs/devel/migration/fixed-ram.rst
> new file mode 100644
> index 0000000000..a6c0e5a360
> --- /dev/null
> +++ b/docs/devel/migration/fixed-ram.rst
> @@ -0,0 +1,137 @@
> +Fixed-ram
> +=========
> +
> +Fixed-ram is a new stream format for the RAM section designed to
> +supplement the existing ``file:`` migration and make it compatible
> +with ``multifd``. This enables parallel migration of a guest's RAM to
> +a file.
> +
> +The core of the feature is to ensure that each RAM page has a specific
> +offset in the resulting migration file. This enables the ``multifd``
> +threads to write exclusively to those offsets even if the guest is
> +constantly dirtying pages (i.e. live migration). Another benefit is
> +that the resulting file will have a bounded size, since pages which
> +are dirtied multiple times will always go to a fixed location in the
> +file, rather than constantly being added to a sequential
> +stream. Having the pages at fixed offsets also allows the usage of
> +O_DIRECT for save/restore of the migration stream as the pages are
> +ensured to be written respecting O_DIRECT alignment restrictions.
> +
> +Usage
> +-----
> +
> +On both source and destination, enable the ``multifd`` and
> +``fixed-ram`` capabilities:
> +
> +    ``migrate_set_capability multifd on``
> +
> +    ``migrate_set_capability fixed-ram on``
> +
> +Use a ``file:`` URL for migration:
> +
> +    ``migrate file:/path/to/migration/file``
> +
> +Fixed-ram migration is best done non-live, i.e. by stopping the VM on
> +the source side before migrating.
> +
> +For best performance enable the ``direct-io`` capability as well:
> +
> +    ``migrate_set_capability direct-io on``
> +
> +Use-cases
> +---------
> +
> +The fixed-ram feature was designed for use cases where the migration
> +stream will be directed to a file in the filesystem and not
> +immediately restored on the destination VM [#]_. These could be
> +thought of as snapshots. We can further categorize them into live and
> +non-live.
> +
> +- Non-live snapshot
> +
> +If the use case requires a VM to be stopped before taking a snapshot,
> +that's the ideal scenario for fixed-ram migration. Not having to track
> +dirty pages, the migration will write the RAM pages to the disk as
> +fast as it can.
> +
> +Note: if a snapshot is taken of a running VM, but the VM will be
> +stopped after the snapshot by the admin, then consider stopping it
> +right before the snapshot to take benefit of the performance gains
> +mentioned above.
> +
> +- Live snapshot
> +
> +If the use case requires that the VM keeps running during and after
> +the snapshot operation, then fixed-ram migration can still be used,
> +but will be less performant. Other strategies such as
> +background-snapshot should be evaluated as well. One benefit of
> +fixed-ram in this scenario is portability since background-snapshot
> +depends on async dirty tracking (KVM_GET_DIRTY_LOG) which is not

Background snapshot uses userfaultfd-wp rather than KVM_GET_DIRTY_LOG.  The
statement is still correct though, that userfault is only supported on
Linux in general (wp is one sub-feature, represents "write-protect mode")
so this should help portability, as it removes the dependency on the OS.

> +supported outside of Linux.
> +
> +.. [#] While this same effect could be obtained with the usage of
> +       snapshots or the ``file:`` migration alone, fixed-ram provides
> +       a performance increase for VMs with larger RAM sizes (10s to
> +       100s of GiBs), specially if the VM has been stopped beforehand.
> +
> +RAM section format
> +------------------
> +
> +Instead of having a sequential stream of pages that follow the
> +RAMBlock headers, the dirty pages for a RAMBlock follow its header
> +instead. This ensures that each RAM page has a fixed offset in the
> +resulting migration file.
> +
> +A bitmap is introduced to track which pages have been written in the
> +migration file. Pages are written at a fixed location for every
> +ramblock. Zero pages are ignored as they'd be zero in the destination
> +migration as well.
> +
> +::
> +
> + Without fixed-ram:                  With fixed-ram:
> +
> + ---------------------               --------------------------------
> + | ramblock 1 header |               | ramblock 1 header            |
> + ---------------------               --------------------------------
> + | ramblock 2 header |               | ramblock 1 fixed-ram header  |
> + ---------------------               --------------------------------
> + | ...               |               | padding to next 1MB boundary |
> + ---------------------               | ...                          |
> + | ramblock n header |               --------------------------------
> + ---------------------               | ramblock 1 pages             |
> + | RAM_SAVE_FLAG_EOS |               | ...                          |
> + ---------------------               --------------------------------
> + | stream of pages   |               | ramblock 2 header            |
> + | (iter 1)          |               --------------------------------
> + | ...               |               | ramblock 2 fixed-ram header  |
> + ---------------------               --------------------------------
> + | RAM_SAVE_FLAG_EOS |               | padding to next 1MB boundary |
> + ---------------------               | ...                          |
> + | stream of pages   |               --------------------------------
> + | (iter 2)          |               | ramblock 2 pages             |
> + | ...               |               | ...                          |
> + ---------------------               --------------------------------
> + | ...               |               | ...                          |
> + ---------------------               --------------------------------
> +                                     | RAM_SAVE_FLAG_EOS            |
> +                                     --------------------------------
> +                                     | ...                          |
> +                                     --------------------------------
> +
> + where:
> +  - ramblock header: the generic information for a ramblock, such as
> +    idstr, used_len, etc.
> +
> +  - ramblock fixed-ram header: the information added by this feature:
> +    bitmap of pages written, bitmap size and offset of pages in the
> +    migration file.
> +
> +Restrictions
> +------------
> +
> +Since pages are written to their relative offsets and out of order
> +(due to the memory dirtying patterns), streaming channels such as
> +sockets are not supported. A seekable channel such as a file is
> +required. This can be verified in the QIOChannel by the presence of
> +the QIO_CHANNEL_FEATURE_SEEKABLE.
> diff --git a/migration/options.c b/migration/options.c
> index 3e3e0b93b4..4909e5c72a 100644
> --- a/migration/options.c
> +++ b/migration/options.c
> @@ -204,6 +204,7 @@ Property migration_properties[] = {
>      DEFINE_PROP_MIG_CAP("x-switchover-ack",
>                          MIGRATION_CAPABILITY_SWITCHOVER_ACK),
>      DEFINE_PROP_MIG_CAP("x-dirty-limit", MIGRATION_CAPABILITY_DIRTY_LIMIT),
> +    DEFINE_PROP_MIG_CAP("x-fixed-ram", MIGRATION_CAPABILITY_FIXED_RAM),

Let's directly use "fixed-ram" (or "mapped-ram", or whatever new name we
decide to use, as long as without "x-")?

migration_properties is not documented anywhere, mostly yet for debugging
purpose.  We could have dropped all the "x-"s, IMHO.

>      DEFINE_PROP_END_OF_LIST(),
>  };
>  
> @@ -263,6 +264,13 @@ bool migrate_events(void)
>      return s->capabilities[MIGRATION_CAPABILITY_EVENTS];
>  }
>  
> +bool migrate_fixed_ram(void)
> +{
> +    MigrationState *s = migrate_get_current();
> +
> +    return s->capabilities[MIGRATION_CAPABILITY_FIXED_RAM];
> +}
> +
>  bool migrate_ignore_shared(void)
>  {
>      MigrationState *s = migrate_get_current();
> @@ -645,6 +653,32 @@ bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
>          }
>      }
>  
> +    if (new_caps[MIGRATION_CAPABILITY_FIXED_RAM]) {
> +        if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
> +            error_setg(errp,
> +                       "Fixed-ram migration is incompatible with multifd");
> +            return false;
> +        }
> +
> +        if (new_caps[MIGRATION_CAPABILITY_XBZRLE]) {
> +            error_setg(errp,
> +                       "Fixed-ram migration is incompatible with xbzrle");
> +            return false;
> +        }
> +
> +        if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) {
> +            error_setg(errp,
> +                       "Fixed-ram migration is incompatible with compression");
> +            return false;
> +        }
> +
> +        if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
> +            error_setg(errp,
> +                       "Fixed-ram migration is incompatible with postcopy ram");
> +            return false;
> +        }
> +    }
> +
>      return true;
>  }
>  
> diff --git a/migration/options.h b/migration/options.h
> index 246c160aee..8680a10b79 100644
> --- a/migration/options.h
> +++ b/migration/options.h
> @@ -31,6 +31,7 @@ bool migrate_compress(void);
>  bool migrate_dirty_bitmaps(void);
>  bool migrate_dirty_limit(void);
>  bool migrate_events(void);
> +bool migrate_fixed_ram(void);
>  bool migrate_ignore_shared(void);
>  bool migrate_late_block_activate(void);
>  bool migrate_multifd(void);
> diff --git a/migration/savevm.c b/migration/savevm.c
> index d612c8a902..4b928dd6bb 100644
> --- a/migration/savevm.c
> +++ b/migration/savevm.c
> @@ -245,6 +245,7 @@ static bool should_validate_capability(int capability)
>      /* Validate only new capabilities to keep compatibility. */
>      switch (capability) {
>      case MIGRATION_CAPABILITY_X_IGNORE_SHARED:
> +    case MIGRATION_CAPABILITY_FIXED_RAM:
>          return true;
>      default:
>          return false;
> diff --git a/qapi/migration.json b/qapi/migration.json
> index 5a565d9b8d..3fce5fe53e 100644
> --- a/qapi/migration.json
> +++ b/qapi/migration.json
> @@ -531,6 +531,10 @@
>  #     and can result in more stable read performance.  Requires KVM
>  #     with accelerator property "dirty-ring-size" set.  (Since 8.1)
>  #
> +# @fixed-ram: Migrate using fixed offsets in the migration file for
> +#     each RAM page.  Requires a migration URI that supports seeking,
> +#     such as a file.  (since 9.0)
> +#
>  # Features:
>  #
>  # @deprecated: Member @block is deprecated.  Use blockdev-mirror with
> @@ -555,7 +559,7 @@
>             { 'name': 'x-ignore-shared', 'features': [ 'unstable' ] },
>             'validate-uuid', 'background-snapshot',
>             'zero-copy-send', 'postcopy-preempt', 'switchover-ack',
> -           'dirty-limit'] }
> +           'dirty-limit', 'fixed-ram'] }
>  
>  ##
>  # @MigrationCapabilityStatus:
> -- 
> 2.35.3
> 

-- 
Peter Xu



  parent reply	other threads:[~2024-02-26  3:08 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-20 22:41 [PATCH v4 00/34] migration: File based migration with multifd and fixed-ram Fabiano Rosas
2024-02-20 22:41 ` [PATCH v4 01/34] docs/devel/migration.rst: Document the file transport Fabiano Rosas
2024-02-23  3:01   ` Peter Xu
2024-02-20 22:41 ` [PATCH v4 02/34] tests/qtest/migration: Rename fd_proto test Fabiano Rosas
2024-02-23  3:03   ` Peter Xu
2024-02-20 22:41 ` [PATCH v4 03/34] tests/qtest/migration: Add a fd + file test Fabiano Rosas
2024-02-23  3:08   ` Peter Xu
2024-02-20 22:41 ` [PATCH v4 04/34] migration/multifd: Remove p->quit from recv side Fabiano Rosas
2024-02-23  3:13   ` Peter Xu
2024-02-20 22:41 ` [PATCH v4 05/34] migration/multifd: Release recv sem_sync earlier Fabiano Rosas
2024-02-23  3:16   ` Peter Xu
2024-02-20 22:41 ` [PATCH v4 06/34] io: add and implement QIO_CHANNEL_FEATURE_SEEKABLE for channel file Fabiano Rosas
2024-02-20 22:41 ` [PATCH v4 07/34] io: Add generic pwritev/preadv interface Fabiano Rosas
2024-02-20 22:41 ` [PATCH v4 08/34] io: implement io_pwritev/preadv for QIOChannelFile Fabiano Rosas
2024-02-20 22:41 ` [PATCH v4 09/34] io: fsync before closing a file channel Fabiano Rosas
2024-02-20 22:41 ` [PATCH v4 10/34] migration/qemu-file: add utility methods for working with seekable channels Fabiano Rosas
2024-02-20 22:41 ` [PATCH v4 11/34] migration/ram: Introduce 'fixed-ram' migration capability Fabiano Rosas
2024-02-21  8:41   ` Markus Armbruster
2024-02-21 13:24     ` Fabiano Rosas
2024-02-21 13:50       ` Daniel P. Berrangé
2024-02-21 15:05         ` Fabiano Rosas
2024-02-26  3:07   ` Peter Xu [this message]
2024-02-26  3:22   ` Peter Xu
2024-02-20 22:41 ` [PATCH v4 12/34] migration: Add fixed-ram URI compatibility check Fabiano Rosas
2024-02-26  3:11   ` Peter Xu
2024-02-20 22:41 ` [PATCH v4 13/34] migration/ram: Add outgoing 'fixed-ram' migration Fabiano Rosas
2024-02-26  4:03   ` Peter Xu
2024-02-20 22:41 ` [PATCH v4 14/34] migration/ram: Add incoming " Fabiano Rosas
2024-02-26  5:19   ` Peter Xu
2024-02-20 22:41 ` [PATCH v4 15/34] tests/qtest/migration: Add tests for fixed-ram file-based migration Fabiano Rosas
2024-02-20 22:41 ` [PATCH v4 16/34] migration/multifd: Rename MultiFDSend|RecvParams::data to compress_data Fabiano Rosas
2024-02-20 22:41 ` [PATCH v4 17/34] migration/multifd: Decouple recv method from pages Fabiano Rosas
2024-02-20 22:41 ` [PATCH v4 18/34] migration/multifd: Allow multifd without packets Fabiano Rosas
2024-02-26  5:57   ` Peter Xu
2024-02-20 22:41 ` [PATCH v4 19/34] migration/multifd: Allow receiving pages " Fabiano Rosas
2024-02-26  6:58   ` Peter Xu
2024-02-26 19:19     ` Fabiano Rosas
2024-02-26 20:54       ` Fabiano Rosas
2024-02-20 22:41 ` [PATCH v4 20/34] migration/multifd: Add outgoing QIOChannelFile support Fabiano Rosas
2024-02-26  7:10   ` Peter Xu
2024-02-26  7:21   ` Peter Xu
2024-02-20 22:41 ` [PATCH v4 21/34] migration/multifd: Add incoming " Fabiano Rosas
2024-02-26  7:34   ` Peter Xu
2024-02-26  7:53     ` Peter Xu
2024-02-20 22:41 ` [PATCH v4 22/34] migration/multifd: Prepare multifd sync for fixed-ram migration Fabiano Rosas
2024-02-26  7:47   ` Peter Xu
2024-02-26 22:52     ` Fabiano Rosas
2024-02-27  3:52       ` Peter Xu
2024-02-27 14:00         ` Fabiano Rosas
2024-02-27 23:46           ` Peter Xu
2024-02-20 22:41 ` [PATCH v4 23/34] migration/multifd: Support outgoing fixed-ram stream format Fabiano Rosas
2024-02-26  8:08   ` Peter Xu
2024-02-20 22:41 ` [PATCH v4 24/34] migration/multifd: Support incoming " Fabiano Rosas
2024-02-26  8:30   ` Peter Xu
2024-02-20 22:41 ` [PATCH v4 25/34] migration/multifd: Add fixed-ram support to fd: URI Fabiano Rosas
2024-02-26  8:37   ` Peter Xu
2024-02-20 22:41 ` [PATCH v4 26/34] tests/qtest/migration: Add a multifd + fixed-ram migration test Fabiano Rosas
2024-02-26  8:42   ` Peter Xu
2024-02-20 22:41 ` [PATCH v4 27/34] migration: Add direct-io parameter Fabiano Rosas
2024-02-21  9:17   ` Markus Armbruster
2024-02-26  8:50   ` Peter Xu
2024-02-26 13:28     ` Fabiano Rosas
2024-02-20 22:41 ` [PATCH v4 28/34] migration/multifd: Add direct-io support Fabiano Rosas
2024-02-20 22:41 ` [PATCH v4 29/34] tests/qtest/migration: Add tests for file migration with direct-io Fabiano Rosas
2024-02-20 22:41 ` [PATCH v4 30/34] monitor: Honor QMP request for fd removal immediately Fabiano Rosas
2024-02-21  9:20   ` Markus Armbruster
2024-02-20 22:41 ` [PATCH v4 31/34] monitor: Extract fdset fd flags comparison into a function Fabiano Rosas
2024-02-20 22:41 ` [PATCH v4 32/34] monitor: fdset: Match against O_DIRECT Fabiano Rosas
2024-02-21  9:27   ` Markus Armbruster
2024-02-21 13:37     ` Fabiano Rosas
2024-02-22  6:56       ` Markus Armbruster
2024-02-22 13:26         ` Fabiano Rosas
2024-02-22 14:44           ` Markus Armbruster
2024-02-20 22:41 ` [PATCH v4 33/34] migration: Add support for fdset with multifd + file Fabiano Rosas
2024-02-20 22:41 ` [PATCH v4 34/34] tests/qtest/migration: Add a test for fixed-ram with passing of fds Fabiano Rosas
2024-02-23  2:59 ` [PATCH v4 00/34] migration: File based migration with multifd and fixed-ram Peter Xu
2024-02-23 13:48   ` Claudio Fontana
2024-02-23 14:22   ` Fabiano Rosas
2024-02-26  6:15 ` Peter Xu

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=ZdwAbW3sHZin-gV0@x1n \
    --to=peterx@redhat.com \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=cfontana@suse.de \
    --cc=eblake@redhat.com \
    --cc=farosas@suse.de \
    --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).