qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [RFC PATCH] migration: reintroduce skipped zero pages


From: Juan Quintela
Subject: Re: [Qemu-devel] [RFC PATCH] migration: reintroduce skipped zero pages
Date: Mon, 12 May 2014 12:02:47 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux)

Peter Lieven <address@hidden> wrote:
> commit f1c72795a introduced skipping of all zero pages during
> bulk phase of ram migration. In theory this should have worked,
> however the underlying assumption that the memory of target VM
> is totally empty (zeroed) was wrong. Altough qemu accepts an incoming
> migration BIOS, ROMs or tables are set up. If e.g. a ROM differs
> between source and target we get memory corruption if a page
> is zero at the source and not at the target. Therefore the
> original patch was reverted later on.
>
> This patch now reintroduces the feature to skip zero pages.
> However, this time it has to be explicitely turned on through
> a migration capability which should only be enabled if both
> source and destination support it.
>
> The feature especially makes sense if you expect a significant portion
> of zero pages while bandwidth or disk space is limited.
> Because even if a zero page is compressed we still transfer 9 bytes for
> each page.
>
> Signed-off-by: Peter Lieven <address@hidden>
> ---
>  arch_init.c                   |   44 
> +++++++++++++++++++++++++++++++++--------
>  include/migration/migration.h |    2 +-
>  migration.c                   |    9 +++++++++
>  qapi-schema.json              |   11 ++++++++---
>  4 files changed, 54 insertions(+), 12 deletions(-)
>
> diff --git a/arch_init.c b/arch_init.c
> index 995f56d..2579302 100644
> --- a/arch_init.c
> +++ b/arch_init.c
> @@ -123,7 +123,8 @@ static uint64_t bitmap_sync_count;
>  #define RAM_SAVE_FLAG_EOS      0x10
>  #define RAM_SAVE_FLAG_CONTINUE 0x20
>  #define RAM_SAVE_FLAG_XBZRLE   0x40
> -/* 0x80 is reserved in migration.h start with 0x100 next */
> +/* 0x80 is reserved in migration.h */
> +#define RAM_SAVE_FLAG_ZERO_TARGET 0x100
>  
>  static struct defconfig_file {
>      const char *filename;
> @@ -575,8 +576,9 @@ static int ram_save_block(QEMUFile *f, bool last_stage)
>      MemoryRegion *mr;
>      ram_addr_t current_addr;
>  
> -    if (!block)
> +    if (!block) {
>          block = QTAILQ_FIRST(&ram_list.blocks);
> +    }
>  
>      while (true) {
>          mr = block->mr;
> @@ -619,11 +621,16 @@ static int ram_save_block(QEMUFile *f, bool last_stage)
>                      }
>                  }
>              } else if (is_zero_range(p, TARGET_PAGE_SIZE)) {
> -                acct_info.dup_pages++;
> -                bytes_sent = save_block_hdr(f, block, offset, cont,
> -                                            RAM_SAVE_FLAG_COMPRESS);
> -                qemu_put_byte(f, 0);
> -                bytes_sent++;
> +                if (!ram_bulk_stage || !migrate_skip_zero_pages()) {
> +                    acct_info.dup_pages++;
> +                    bytes_sent = save_block_hdr(f, block, offset, cont,
> +                                                RAM_SAVE_FLAG_COMPRESS);
> +                    qemu_put_byte(f, 0);
> +                    bytes_sent++;
> +                } else {
> +                    acct_info.skipped_pages++;
> +                    bytes_sent = 0;
> +                }
>                  /* Must let xbzrle know, otherwise a previous (now 0'd) 
> cached
>                   * page would be stale
>                   */
> @@ -752,6 +759,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
>  {
>      RAMBlock *block;
>      int64_t ram_bitmap_pages; /* Size of bitmap in pages, including gaps */
> +    uint64_t flags = 0;

       flags = RAM_SAVE_FLAG_MEM_SIZE;


>  
>      mig_throttle_on = false;
>      dirty_rate_high_cnt = 0;
> @@ -812,7 +820,11 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
>      migration_bitmap_sync();
>      qemu_mutex_unlock_iothread();
>  
> -    qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE);
> +    if (migrate_skip_zero_pages()) {
> +        flags |= RAM_SAVE_FLAG_ZERO_TARGET;
> +    }
> +
> +    qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE | flags);

       qemu_put_be64(f, ram_bytes_total() | flags);

??


Could someone from pseries take a look?

Thanks, Juan.



reply via email to

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