|
|
eb5a2f |
From a00bde30c0730d3434d9f4556a9cb119f3f8d68d Mon Sep 17 00:00:00 2001
|
|
|
eb5a2f |
From: Dr. David Alan Gilbert (git) <dgilbert@redhat.com>
|
|
|
eb5a2f |
Date: Thu, 8 May 2014 10:58:42 +0200
|
|
|
eb5a2f |
Subject: [PATCH 20/30] XBZRLE: Fix one XBZRLE corruption issues
|
|
|
eb5a2f |
|
|
|
eb5a2f |
RH-Author: Dr. David Alan Gilbert (git) <dgilbert@redhat.com>
|
|
|
eb5a2f |
Message-id: <1399546722-6350-5-git-send-email-dgilbert@redhat.com>
|
|
|
eb5a2f |
Patchwork-id: 58744
|
|
|
eb5a2f |
O-Subject: [RHEL7.1/RHEL7.0.z qemu-kvm PATCH 4/4] XBZRLE: Fix one XBZRLE corruption issues
|
|
|
eb5a2f |
Bugzilla: 1110191
|
|
|
eb5a2f |
RH-Acked-by: Juan Quintela <quintela@redhat.com>
|
|
|
eb5a2f |
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
|
|
eb5a2f |
RH-Acked-by: Amit Shah <amit.shah@redhat.com>
|
|
|
eb5a2f |
|
|
|
eb5a2f |
From: ChenLiang <chenliang88@huawei.com>
|
|
|
eb5a2f |
|
|
|
eb5a2f |
The page may not be inserted into cache after executing save_xbzrle_page.
|
|
|
eb5a2f |
In case of failure to insert, the original page should be sent rather
|
|
|
eb5a2f |
than the page in the cache.
|
|
|
eb5a2f |
|
|
|
eb5a2f |
Signed-off-by: ChenLiang <chenliang88@huawei.com>
|
|
|
eb5a2f |
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
|
|
|
eb5a2f |
Reviewed-by: Juan Quintela <quintela@redhat.com>
|
|
|
eb5a2f |
Signed-off-by: Juan Quintela <quintela@redhat.com>
|
|
|
eb5a2f |
(cherry picked from commit 1534ee93cc6be992c05577886b24bd44c37ecff6)
|
|
|
eb5a2f |
---
|
|
|
eb5a2f |
arch_init.c | 25 +++++++++++++------------
|
|
|
eb5a2f |
1 file changed, 13 insertions(+), 12 deletions(-)
|
|
|
eb5a2f |
|
|
|
eb5a2f |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
eb5a2f |
---
|
|
|
eb5a2f |
arch_init.c | 25 +++++++++++++------------
|
|
|
eb5a2f |
1 files changed, 13 insertions(+), 12 deletions(-)
|
|
|
eb5a2f |
|
|
|
eb5a2f |
diff --git a/arch_init.c b/arch_init.c
|
|
|
eb5a2f |
index 80e48f2..22f7def 100644
|
|
|
eb5a2f |
--- a/arch_init.c
|
|
|
eb5a2f |
+++ b/arch_init.c
|
|
|
eb5a2f |
@@ -341,7 +341,7 @@ static void xbzrle_cache_zero_page(ram_addr_t current_addr)
|
|
|
eb5a2f |
|
|
|
eb5a2f |
#define ENCODING_FLAG_XBZRLE 0x1
|
|
|
eb5a2f |
|
|
|
eb5a2f |
-static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
|
|
|
eb5a2f |
+static int save_xbzrle_page(QEMUFile *f, uint8_t **current_data,
|
|
|
eb5a2f |
ram_addr_t current_addr, RAMBlock *block,
|
|
|
eb5a2f |
ram_addr_t offset, int cont, bool last_stage)
|
|
|
eb5a2f |
{
|
|
|
eb5a2f |
@@ -349,19 +349,23 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
|
|
|
eb5a2f |
uint8_t *prev_cached_page;
|
|
|
eb5a2f |
|
|
|
eb5a2f |
if (!cache_is_cached(XBZRLE.cache, current_addr)) {
|
|
|
eb5a2f |
+ acct_info.xbzrle_cache_miss++;
|
|
|
eb5a2f |
if (!last_stage) {
|
|
|
eb5a2f |
- if (cache_insert(XBZRLE.cache, current_addr, current_data) == -1) {
|
|
|
eb5a2f |
+ if (cache_insert(XBZRLE.cache, current_addr, *current_data) == -1) {
|
|
|
eb5a2f |
return -1;
|
|
|
eb5a2f |
+ } else {
|
|
|
eb5a2f |
+ /* update *current_data when the page has been
|
|
|
eb5a2f |
+ inserted into cache */
|
|
|
eb5a2f |
+ *current_data = get_cached_data(XBZRLE.cache, current_addr);
|
|
|
eb5a2f |
}
|
|
|
eb5a2f |
}
|
|
|
eb5a2f |
- acct_info.xbzrle_cache_miss++;
|
|
|
eb5a2f |
return -1;
|
|
|
eb5a2f |
}
|
|
|
eb5a2f |
|
|
|
eb5a2f |
prev_cached_page = get_cached_data(XBZRLE.cache, current_addr);
|
|
|
eb5a2f |
|
|
|
eb5a2f |
/* save current buffer into memory */
|
|
|
eb5a2f |
- memcpy(XBZRLE.current_buf, current_data, TARGET_PAGE_SIZE);
|
|
|
eb5a2f |
+ memcpy(XBZRLE.current_buf, *current_data, TARGET_PAGE_SIZE);
|
|
|
eb5a2f |
|
|
|
eb5a2f |
/* XBZRLE encoding (if there is no overflow) */
|
|
|
eb5a2f |
encoded_len = xbzrle_encode_buffer(prev_cached_page, XBZRLE.current_buf,
|
|
|
eb5a2f |
@@ -374,7 +378,10 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
|
|
|
eb5a2f |
DPRINTF("Overflow\n");
|
|
|
eb5a2f |
acct_info.xbzrle_overflows++;
|
|
|
eb5a2f |
/* update data in the cache */
|
|
|
eb5a2f |
- memcpy(prev_cached_page, current_data, TARGET_PAGE_SIZE);
|
|
|
eb5a2f |
+ if (!last_stage) {
|
|
|
eb5a2f |
+ memcpy(prev_cached_page, *current_data, TARGET_PAGE_SIZE);
|
|
|
eb5a2f |
+ *current_data = prev_cached_page;
|
|
|
eb5a2f |
+ }
|
|
|
eb5a2f |
return -1;
|
|
|
eb5a2f |
}
|
|
|
eb5a2f |
|
|
|
eb5a2f |
@@ -599,15 +606,9 @@ static int ram_save_block(QEMUFile *f, bool last_stage)
|
|
|
eb5a2f |
*/
|
|
|
eb5a2f |
xbzrle_cache_zero_page(current_addr);
|
|
|
eb5a2f |
} else if (!ram_bulk_stage && migrate_use_xbzrle()) {
|
|
|
eb5a2f |
- bytes_sent = save_xbzrle_page(f, p, current_addr, block,
|
|
|
eb5a2f |
+ bytes_sent = save_xbzrle_page(f, &p, current_addr, block,
|
|
|
eb5a2f |
offset, cont, last_stage);
|
|
|
eb5a2f |
if (!last_stage) {
|
|
|
eb5a2f |
- /* We must send exactly what's in the xbzrle cache
|
|
|
eb5a2f |
- * even if the page wasn't xbzrle compressed, so that
|
|
|
eb5a2f |
- * it's right next time.
|
|
|
eb5a2f |
- */
|
|
|
eb5a2f |
- p = get_cached_data(XBZRLE.cache, current_addr);
|
|
|
eb5a2f |
-
|
|
|
eb5a2f |
/* Can't send this cached data async, since the cache page
|
|
|
eb5a2f |
* might get updated before it gets to the wire
|
|
|
eb5a2f |
*/
|
|
|
eb5a2f |
--
|
|
|
eb5a2f |
1.7.1
|
|
|
eb5a2f |
|