[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [RFC PATCH] migration: reintroduce skipped zero pages
From: |
Peter Lieven |
Subject: |
Re: [Qemu-devel] [RFC PATCH] migration: reintroduce skipped zero pages |
Date: |
Mon, 12 May 2014 12:10:15 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.4.0 |
Am 12.05.2014 12:02, schrieb Juan Quintela:
> 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?
Yes, that would be great.
I was also wondering if we write anything into pc.ram or *.ram segment or just
into
the other regions?
Peter
>
> Thanks, Juan.