fix migration of zero pages
v2 cover fix migration of zero pages
There have been reports that migration is broken on pseries by Alexey Kardashevskiy. It turned out that migration will fail in general as soon as a page is zero on the source, but not on the destination. I thus reverted the skipping of zero pages in bulk transfer phase and added a patch that does not (over)write zero pages at the destination.
v2:
- keep skipped pages fields in monitoring and qmp intact to avoid compatiblity issues.
Peter Lieven (2):
Revert "migration: do not sent zero pages in bulk stage"
migration: do not overwrite zero pages
arch_init.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-)
Signature · 1 line
1.7.9.5
PATCH v2 1/2 Revert "migration: do not sent zero pages in bulk stage"
Not sending zero pages breaks migration if a page is zero at the source but not at the destination. This can e.g. happen if different BIOS versions are used at source and destination. It has also been reported that migration on pseries is completely broken with this patch.
This effectively reverts commit f1c72795af573b24a7da5eb52375c9aba8a37972.
Conflicts:
arch_init.c
--- arch_init.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
arch_init.c +4 -9
@@ -457,15 +457,10 @@ static int ram_save_block(QEMUFile *f, bool last_stage) bytes_sent =-1 ;if (is_zero_page (p)) { acct_info.dup_pages++; -if (!ram_bulk_stage) { - 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 ; - } + bytes_sent =save_block_hdr (f, block, offset, cont, +RAM_SAVE_FLAG_COMPRESS ); +qemu_put_byte (f,0 ); + bytes_sent++; }else if (!ram_bulk_stage &&migrate_use_xbzrle ()) { current_addr = block->offset + offset; bytes_sent = save_xbzrle_page(f, p, current_addr, block,
Signature · 1 line
1.7.9.5
Re: [Qemu-devel] [PATCHv2 1/2] Revert "migration: do not sent zero pages in bulk stage"
Quoted 6 lines · Peter Lieven
Not sending zero pages breaks migration if a page is zero at the source but not at the destination. This can e.g. happen if different BIOS versions are used at source and destination. It has also been reported that migration on pseries is completely broken with this patch.
Quoted 7 lines
This effectively reverts commit
f1c72795af573b24a7da5eb52375c9aba8a37972.Conflicts:
arch_init.cSigned-off-by Peter Lieven <[email protected]>
Also CC'ing qemu-stable
Quoted 32 lines
--- arch_init.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)arch_init.c +4
-9@@ -457,15 +457,10 @@ static int ram_save_block(QEMUFile *f, bool last_stage) bytes_sent =-1 ;if (is_zero_page (p)) { acct_info.dup_pages++; -if (!ram_bulk_stage) { - 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 ; - } + bytes_sent =save_block_hdr (f, block, offset, cont, +RAM_SAVE_FLAG_COMPRESS ); +qemu_put_byte (f,0 ); + bytes_sent++; }else if (!ram_bulk_stage &&migrate_use_xbzrle ()) { current_addr = block->offset + offset; bytes_sent = save_xbzrle_page(f, p, current_addr, block,Signature · 1 line
1.7.9.5
Re: [Qemu-devel] [PATCHv2 1/2] Revert "migration: do not sent zero pages in bulk stage"
In reply to Peter LievenQuoted 32 lines · Peter Lieven
Not sending zero pages breaks migration if a page is zero at the source but not at the destination. This can e.g. happen if different BIOS versions are used at source and destination. It has also been reported that migration on pseries is completely broken with this patch.
This effectively reverts commit
f1c72795af573b24a7da5eb52375c9aba8a37972.Conflicts:
arch_init.cSigned-off-by Peter Lieven <[email protected]>--- arch_init.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)arch_init.c +0
-6@@ -457,15 +457,10 @@ static int ram_save_block(QEMUFile *f, bool last_stage) bytes_sent =-1 ;if (is_zero_page (p)) { acct_info.dup_pages++; -if (!ram_bulk_stage) { - bytes_sent =save_block_hdr (f, block, offset, cont, -RAM_SAVE_FLAG_COMPRESS ); -qemu_put_byte (f,0 ); - bytes_sent++; - }else {
arch_init.c static int ram_save_block(QEMUFile *f, bool last_stage) · line 466
Quoted 10 lines
arch_init.c +4
-3- acct_info.skipped_pages++; - bytes_sent =0 ; - } + bytes_sent =save_block_hdr (f, block, offset, cont, +RAM_SAVE_FLAG_COMPRESS ); +qemu_put_byte (f,0 ); + bytes_sent++; }else if (!ram_bulk_stage &&migrate_use_xbzrle ()) { current_addr = block->offset + offset; bytes_sent = save_xbzrle_page(f, p, current_addr, block,
Re: [Qemu-devel] [PATCHv2 1/2] Revert "migration: do not sent zero pages in bulk stage"
In reply to Peter Lievenclear patch, I don't see any issue.
Quoted 42 lines
Not sending zero pages breaks migration if a page is zero at the source but not at the destination. This can e.g. happen if different BIOS versions are used at source and destination. It has also been reported that migration on pseries is completely broken with this patch.
This effectively reverts commit
f1c72795af573b24a7da5eb52375c9aba8a37972.Conflicts:
arch_init.cSigned-off-by Peter Lieven <[email protected]>--- arch_init.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)arch_init.c +4
-9@@ -457,15 +457,10 @@ static int ram_save_block(QEMUFile *f, bool last_stage) bytes_sent =-1 ;if (is_zero_page (p)) { acct_info.dup_pages++; -if (!ram_bulk_stage) { - 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 ; - } + bytes_sent =save_block_hdr (f, block, offset, cont, +RAM_SAVE_FLAG_COMPRESS ); +qemu_put_byte (f,0 ); + bytes_sent++; }else if (!ram_bulk_stage &&migrate_use_xbzrle ()) { current_addr = block->offset + offset; bytes_sent = save_xbzrle_page(f, p, current_addr, block,
Signature · 3 lines
Best Regards Wenchao Xia
PATCH v2 2/2 migration: do not overwrite zero pages
In reply to Peter Lievenon incoming migration do not memset pages to zero if they already read as zero. this will allocate a new zero page and consume memory unnecessarily. even if we madvise a MADV_DONTNEED later this will only deallocate the memory asynchronously.
--- arch_init.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
arch_init.c +8 -6
@@ -832,14 +832,16 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) } ch =qemu_get_byte (f); -memset (host, ch,TARGET_PAGE_SIZE ); +if (ch !=0 || !is_zero_page (host)) { +memset (host, ch,TARGET_PAGE_SIZE );#ifndef _WIN32 -if (ch ==0 && - (!kvm_enabled () ||kvm_has_sync_mmu ()) && -getpagesize () <=TARGET_PAGE_SIZE ) { -qemu_madvise (host,TARGET_PAGE_SIZE ,QEMU_MADV_DONTNEED ); - } +if (ch ==0 && + (!kvm_enabled () ||kvm_has_sync_mmu ()) && +getpagesize () <=TARGET_PAGE_SIZE ) { +qemu_madvise (host,TARGET_PAGE_SIZE ,QEMU_MADV_DONTNEED ); + }#endif + } }else if (flags &RAM_SAVE_FLAG_PAGE ) {void *host;
Signature · 1 line
1.7.9.5
Re: [Qemu-devel] [PATCHv2 2/2] migration: do not overwrite zero pages
Quoted 22 lines · Peter Lieven
on incoming migration do not memset pages to zero if they already read as zero. this will allocate a new zero page and consume memory unnecessarily. even if we madvise a
MADV_DONTNEEDlater this will only deallocate the memory asynchronously.Signed-off-by Peter Lieven <[email protected]>--- arch_init.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)arch_init.c +2
-1@@ -832,14 +832,16 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) } ch =qemu_get_byte (f); -memset (host, ch,TARGET_PAGE_SIZE ); +if (ch !=0 || !is_zero_page (host)) { +memset (host, ch,TARGET_PAGE_SIZE );#ifndef _WIN32
arch_init.c static int ram_load(QEMUFile *f, void *opaque, int version_id) · line 842
Quoted 10 lines
arch_init.c +5
-5-if (ch ==0 && - (!kvm_enabled () ||kvm_has_sync_mmu ()) && -getpagesize () <=TARGET_PAGE_SIZE ) { -qemu_madvise (host,TARGET_PAGE_SIZE ,QEMU_MADV_DONTNEED ); - } +if (ch ==0 && + (!kvm_enabled () ||kvm_has_sync_mmu ()) && +getpagesize () <=TARGET_PAGE_SIZE ) { +qemu_madvise (host,TARGET_PAGE_SIZE ,QEMU_MADV_DONTNEED ); + }
Also CC'ing qemu-stable, but from what I gather this just mitigates the performance impact of 1/2 and isn't strictly necessary to fix migration? i.e. we can still do outgoing migration to 1.5.0 guests?
Quoted 9 lines
arch_init.c +1
-0#endif + } }else if (flags &RAM_SAVE_FLAG_PAGE ) {void *host;Signature · 1 line
1.7.9.5
Re: [Qemu-devel] [PATCHv2 2/2] migration: do not overwrite zero pages
Quoted 36 lines · mdroth
Quoted 22 lines · Peter Lieven
on incoming migration do not memset pages to zero if they already read as zero. this will allocate a new zero page and consume memory unnecessarily. even if we madvise a
MADV_DONTNEEDlater this will only deallocate the memory asynchronously.Signed-off-by Peter Lieven <[email protected]>--- arch_init.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)arch_init.c +2
-1@@ -832,14 +832,16 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) } ch =qemu_get_byte (f); -memset (host, ch,TARGET_PAGE_SIZE ); +if (ch !=0 || !is_zero_page (host)) { +memset (host, ch,TARGET_PAGE_SIZE );#ifndef _WIN32arch_init.c static int ram_load(QEMUFile *f, void *opaque, int version_id) · line 842
Quoted 10 lines
arch_init.c +5
-5-if (ch ==0 && - (!kvm_enabled () ||kvm_has_sync_mmu ()) && -getpagesize () <=TARGET_PAGE_SIZE ) { -qemu_madvise (host,TARGET_PAGE_SIZE ,QEMU_MADV_DONTNEED ); - } +if (ch ==0 && + (!kvm_enabled () ||kvm_has_sync_mmu ()) && +getpagesize () <=TARGET_PAGE_SIZE ) { +qemu_madvise (host,TARGET_PAGE_SIZE ,QEMU_MADV_DONTNEED ); + }Reviewed-by Michael Roth <[email protected]>
Quoted 1 line
Also CC'ing qemu-stable, but from what I gather this just mitigates the
*actually* CC'ing qemu-stable this time :)
Re: [Qemu-devel] [PATCHv2 2/2] migration: do not overwrite zero pages
In reply to mdrothAm 10.06.2013 um 18:10 schrieb mdroth <[email protected]>:
Quoted 36 lines · Peter Lieven
Quoted 22 lines
on incoming migration do not memset pages to zero if they already read as zero. this will allocate a new zero page and consume memory unnecessarily. even if we madvise a
MADV_DONTNEEDlater this will only deallocate the memory asynchronously.Signed-off-by Peter Lieven <[email protected]>---
arch_init.c| 14 ++++++++------1 file changed, 8 insertions(+), 6 deletions(-)arch_init.c +2
-1@@ -832,14 +832,16 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) } ch =qemu_get_byte (f); -memset (host, ch,TARGET_PAGE_SIZE ); +if (ch !=0 || !is_zero_page (host)) { +memset (host, ch,TARGET_PAGE_SIZE );#ifndef _WIN32arch_init.c static int ram_load(QEMUFile *f, void *opaque, int version_id) · line 842
Quoted 10 lines
arch_init.c +5
-5-if (ch ==0 && - (!kvm_enabled () ||kvm_has_sync_mmu ()) && -getpagesize () <=TARGET_PAGE_SIZE ) { -qemu_madvise (host,TARGET_PAGE_SIZE ,QEMU_MADV_DONTNEED ); - } +if (ch ==0 && + (!kvm_enabled () ||kvm_has_sync_mmu ()) && +getpagesize () <=TARGET_PAGE_SIZE ) { +qemu_madvise (host,TARGET_PAGE_SIZE ,QEMU_MADV_DONTNEED ); + }Reviewed-by Michael Roth <[email protected]>
Quoted 3 lines
Also CC'ing qemu-stable, but from what I gather this just mitigates the performance impact of 1/2 and isn't strictly necessary to fix migration? i.e. we can still do outgoing migration to 1.5.0 guests?
correct. the regression was introduced by the patch that was reverted in 1/2. This patch is just a nice to have to avoid unnecessary allocation of zero pages.
Peter
Re: [Qemu-devel] [PATCHv2 2/2] migration: do not overwrite zero pages
In reply to Peter LievenQuoted 28 lines · Peter Lieven
on incoming migration do not memset pages to zero if they already read as zero. this will allocate a new zero page and consume memory unnecessarily. even if we madvise a
MADV_DONTNEEDlater this will only deallocate the memory asynchronously.Signed-off-by Peter Lieven <[email protected]>--- arch_init.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)arch_init.c +2
-6@@ -832,14 +832,16 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) } ch =qemu_get_byte (f); -memset (host, ch,TARGET_PAGE_SIZE ); +if (ch !=0 || !is_zero_page (host)) { +memset (host, ch,TARGET_PAGE_SIZE );#ifndef _WIN32 -if (ch ==0 && - (!kvm_enabled () ||kvm_has_sync_mmu ()) && -getpagesize () <=TARGET_PAGE_SIZE ) { -qemu_madvise (host,TARGET_PAGE_SIZE ,QEMU_MADV_DONTNEED ); - }
arch_init.c static int ram_load(QEMUFile *f, void *opaque, int version_id) · line 847
Quoted 10 lines
arch_init.c +6
-0+if (ch ==0 && + (!kvm_enabled () ||kvm_has_sync_mmu ()) && +getpagesize () <=TARGET_PAGE_SIZE ) { +qemu_madvise (host,TARGET_PAGE_SIZE ,QEMU_MADV_DONTNEED ); + }#endif + } }else if (flags &RAM_SAVE_FLAG_PAGE ) {void *host;
Re: [Qemu-devel] [PATCHv2 2/2] migration: do not overwrite zero pages
In reply to Peter LievenQuoted 15 lines · Peter Lieven
on incoming migration do not memset pages to zero if they already read as zero. this will allocate a new zero page and consume memory unnecessarily. even if we madvise a
MADV_DONTNEEDlater this will only deallocate the memory asynchronously.Signed-off-by Peter Lieven <[email protected]>--- arch_init.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)arch_init.c +0
-0
arch_init.c static int ram_load(QEMUFile *f, void *opaque, int version_id) · line 835
Quoted 5 lines
arch_init.c +1
-1@@ -832,14 +832,16 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) } ch =qemu_get_byte (f); -memset (host, ch,TARGET_PAGE_SIZE ); +if (ch !=0 || !is_zero_page (host)) {
If incoming page is not zero, always memset. If incoming page is
zero, then if on destination it is not zero, memset. Logic is OK. Only question is if the read operation in is_zero_page() consumes memory, as there are doubt in the discuss before.
Any way this patch will not break migration in my opinion.
Quoted 17 lines
arch_init.c +7
-5+memset (host, ch,TARGET_PAGE_SIZE );#ifndef _WIN32 -if (ch ==0 && - (!kvm_enabled () ||kvm_has_sync_mmu ()) && -getpagesize () <=TARGET_PAGE_SIZE ) { -qemu_madvise (host,TARGET_PAGE_SIZE ,QEMU_MADV_DONTNEED ); - } +if (ch ==0 && + (!kvm_enabled () ||kvm_has_sync_mmu ()) && +getpagesize () <=TARGET_PAGE_SIZE ) { +qemu_madvise (host,TARGET_PAGE_SIZE ,QEMU_MADV_DONTNEED ); + }#endif + } }else if (flags &RAM_SAVE_FLAG_PAGE ) {void *host;
Signature · 3 lines
Best Regards Wenchao Xia
Re: [Qemu-devel] [PATCHv2 2/2] migration: do not overwrite zero pages
Quoted 18 lines · Wenchao Xia
Quoted 17 lines · Peter Lieven
on incoming migration do not memset pages to zero if they already read as zero. this will allocate a new zero page and consume memory unnecessarily. even if we madvise a
MADV_DONTNEEDlater this will only deallocate the memory asynchronously.Signed-off-by Peter Lieven <[email protected]>--- arch_init.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)arch_init.c +0
-0@@ -832,14 +832,16 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) }
Quoted 7 lines
arch_init.c static int ram_load(QEMUFile *f, void *opaque, int version_id) · line 835
Quoted 3 lines
arch_init.c +1
-1ch =qemu_get_byte (f); -memset (host, ch,TARGET_PAGE_SIZE ); +if (ch !=0 || !is_zero_page (host)) {If incoming page is not zero, always memset. If incoming page is
zero, then if on destination it is not zero, memset. Logic is OK. Only question is if the read operation inis_zero_page()consumes memory, as there are doubt in the discuss before.
It does not consume memory for normal pages and for thp since 3.8.
BR,
Peter