|
|
958e1b |
From 7b47ae208675e0da813f9f46838d9a8935c68a02 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:41 +0200
|
|
|
958e1b |
Subject: [PATCH 06/31] Init the XBZRLE.lock in ram_mig_init
|
|
|
eb5a2f |
|
|
|
eb5a2f |
RH-Author: Dr. David Alan Gilbert (git) <dgilbert@redhat.com>
|
|
|
eb5a2f |
Message-id: <1399546722-6350-4-git-send-email-dgilbert@redhat.com>
|
|
|
eb5a2f |
Patchwork-id: 58743
|
|
|
eb5a2f |
O-Subject: [RHEL7.1/RHEL7.0.z qemu-kvm PATCH 3/4] Init the XBZRLE.lock in ram_mig_init
|
|
|
958e1b |
Bugzilla: 1066338
|
|
|
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: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
|
|
|
eb5a2f |
|
|
|
eb5a2f |
Initialising the XBZRLE.lock earlier simplifies the lock use.
|
|
|
eb5a2f |
|
|
|
eb5a2f |
Based on Markus's patch in:
|
|
|
eb5a2f |
http://lists.gnu.org/archive/html/qemu-devel/2014-03/msg03879.html
|
|
|
eb5a2f |
|
|
|
eb5a2f |
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
|
|
eb5a2f |
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
|
|
|
eb5a2f |
Reviewed-by: Markus Armbruster <armbru@redhat.com>
|
|
|
eb5a2f |
Signed-off-by: Juan Quintela <quintela@redhat.com>
|
|
|
eb5a2f |
(cherry picked from commit d97326eec2ca1313eaf0b5cffd69af5663b5af5d)
|
|
|
eb5a2f |
---
|
|
|
eb5a2f |
arch_init.c | 61 +++++++++++++++++++++++++++++++------------------------------
|
|
|
eb5a2f |
1 file changed, 31 insertions(+), 30 deletions(-)
|
|
|
eb5a2f |
|
|
|
eb5a2f |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
eb5a2f |
---
|
|
|
eb5a2f |
arch_init.c | 61 ++++++++++++++++++++++++++++++-----------------------------
|
|
|
eb5a2f |
1 files changed, 31 insertions(+), 30 deletions(-)
|
|
|
eb5a2f |
|
|
|
eb5a2f |
diff --git a/arch_init.c b/arch_init.c
|
|
|
eb5a2f |
index 37c9f6d..80e48f2 100644
|
|
|
eb5a2f |
--- a/arch_init.c
|
|
|
eb5a2f |
+++ b/arch_init.c
|
|
|
eb5a2f |
@@ -45,6 +45,7 @@
|
|
|
eb5a2f |
#include "hw/audio/pcspk.h"
|
|
|
eb5a2f |
#include "migration/page_cache.h"
|
|
|
eb5a2f |
#include "qemu/config-file.h"
|
|
|
eb5a2f |
+#include "qemu/error-report.h"
|
|
|
eb5a2f |
#include "qmp-commands.h"
|
|
|
eb5a2f |
#include "trace.h"
|
|
|
eb5a2f |
#include "exec/cpu-all.h"
|
|
|
eb5a2f |
@@ -167,11 +168,8 @@ static struct {
|
|
|
eb5a2f |
/* Cache for XBZRLE, Protected by lock. */
|
|
|
eb5a2f |
PageCache *cache;
|
|
|
eb5a2f |
QemuMutex lock;
|
|
|
eb5a2f |
-} XBZRLE = {
|
|
|
eb5a2f |
- .encoded_buf = NULL,
|
|
|
eb5a2f |
- .current_buf = NULL,
|
|
|
eb5a2f |
- .cache = NULL,
|
|
|
eb5a2f |
-};
|
|
|
eb5a2f |
+} XBZRLE;
|
|
|
eb5a2f |
+
|
|
|
eb5a2f |
/* buffer used for XBZRLE decoding */
|
|
|
eb5a2f |
static uint8_t *xbzrle_decoded_buf;
|
|
|
eb5a2f |
|
|
|
eb5a2f |
@@ -187,41 +185,44 @@ static void XBZRLE_cache_unlock(void)
|
|
|
eb5a2f |
qemu_mutex_unlock(&XBZRLE.lock);
|
|
|
eb5a2f |
}
|
|
|
eb5a2f |
|
|
|
eb5a2f |
+/*
|
|
|
eb5a2f |
+ * called from qmp_migrate_set_cache_size in main thread, possibly while
|
|
|
eb5a2f |
+ * a migration is in progress.
|
|
|
eb5a2f |
+ * A running migration maybe using the cache and might finish during this
|
|
|
eb5a2f |
+ * call, hence changes to the cache are protected by XBZRLE.lock().
|
|
|
eb5a2f |
+ */
|
|
|
eb5a2f |
int64_t xbzrle_cache_resize(int64_t new_size)
|
|
|
eb5a2f |
{
|
|
|
eb5a2f |
- PageCache *new_cache, *cache_to_free;
|
|
|
eb5a2f |
+ PageCache *new_cache;
|
|
|
eb5a2f |
+ int64_t ret;
|
|
|
eb5a2f |
|
|
|
eb5a2f |
if (new_size < TARGET_PAGE_SIZE) {
|
|
|
eb5a2f |
return -1;
|
|
|
eb5a2f |
}
|
|
|
eb5a2f |
|
|
|
eb5a2f |
- /* no need to lock, the current thread holds qemu big lock */
|
|
|
eb5a2f |
+ XBZRLE_cache_lock();
|
|
|
eb5a2f |
+
|
|
|
eb5a2f |
if (XBZRLE.cache != NULL) {
|
|
|
eb5a2f |
- /* check XBZRLE.cache again later */
|
|
|
eb5a2f |
if (pow2floor(new_size) == migrate_xbzrle_cache_size()) {
|
|
|
eb5a2f |
- return pow2floor(new_size);
|
|
|
eb5a2f |
+ goto out_new_size;
|
|
|
eb5a2f |
}
|
|
|
eb5a2f |
new_cache = cache_init(new_size / TARGET_PAGE_SIZE,
|
|
|
eb5a2f |
TARGET_PAGE_SIZE);
|
|
|
eb5a2f |
if (!new_cache) {
|
|
|
eb5a2f |
- DPRINTF("Error creating cache\n");
|
|
|
eb5a2f |
- return -1;
|
|
|
eb5a2f |
- }
|
|
|
eb5a2f |
-
|
|
|
eb5a2f |
- XBZRLE_cache_lock();
|
|
|
eb5a2f |
- /* the XBZRLE.cache may have be destroyed, check it again */
|
|
|
eb5a2f |
- if (XBZRLE.cache != NULL) {
|
|
|
eb5a2f |
- cache_to_free = XBZRLE.cache;
|
|
|
eb5a2f |
- XBZRLE.cache = new_cache;
|
|
|
eb5a2f |
- } else {
|
|
|
eb5a2f |
- cache_to_free = new_cache;
|
|
|
eb5a2f |
+ error_report("Error creating cache");
|
|
|
eb5a2f |
+ ret = -1;
|
|
|
eb5a2f |
+ goto out;
|
|
|
eb5a2f |
}
|
|
|
eb5a2f |
- XBZRLE_cache_unlock();
|
|
|
eb5a2f |
|
|
|
eb5a2f |
- cache_fini(cache_to_free);
|
|
|
eb5a2f |
+ cache_fini(XBZRLE.cache);
|
|
|
eb5a2f |
+ XBZRLE.cache = new_cache;
|
|
|
eb5a2f |
}
|
|
|
eb5a2f |
|
|
|
eb5a2f |
- return pow2floor(new_size);
|
|
|
eb5a2f |
+out_new_size:
|
|
|
eb5a2f |
+ ret = pow2floor(new_size);
|
|
|
eb5a2f |
+out:
|
|
|
eb5a2f |
+ XBZRLE_cache_unlock();
|
|
|
eb5a2f |
+ return ret;
|
|
|
eb5a2f |
}
|
|
|
eb5a2f |
|
|
|
eb5a2f |
/* accounting for migration statistics */
|
|
|
eb5a2f |
@@ -735,28 +736,27 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
|
|
|
eb5a2f |
dirty_rate_high_cnt = 0;
|
|
|
eb5a2f |
|
|
|
eb5a2f |
if (migrate_use_xbzrle()) {
|
|
|
eb5a2f |
- qemu_mutex_lock_iothread();
|
|
|
eb5a2f |
+ XBZRLE_cache_lock();
|
|
|
eb5a2f |
XBZRLE.cache = cache_init(migrate_xbzrle_cache_size() /
|
|
|
eb5a2f |
TARGET_PAGE_SIZE,
|
|
|
eb5a2f |
TARGET_PAGE_SIZE);
|
|
|
eb5a2f |
if (!XBZRLE.cache) {
|
|
|
eb5a2f |
- qemu_mutex_unlock_iothread();
|
|
|
eb5a2f |
- DPRINTF("Error creating cache\n");
|
|
|
eb5a2f |
+ XBZRLE_cache_unlock();
|
|
|
eb5a2f |
+ error_report("Error creating cache");
|
|
|
eb5a2f |
return -1;
|
|
|
eb5a2f |
}
|
|
|
eb5a2f |
- qemu_mutex_init(&XBZRLE.lock);
|
|
|
eb5a2f |
- qemu_mutex_unlock_iothread();
|
|
|
eb5a2f |
+ XBZRLE_cache_unlock();
|
|
|
eb5a2f |
|
|
|
eb5a2f |
/* We prefer not to abort if there is no memory */
|
|
|
eb5a2f |
XBZRLE.encoded_buf = g_try_malloc0(TARGET_PAGE_SIZE);
|
|
|
eb5a2f |
if (!XBZRLE.encoded_buf) {
|
|
|
eb5a2f |
- DPRINTF("Error allocating encoded_buf\n");
|
|
|
eb5a2f |
+ error_report("Error allocating encoded_buf");
|
|
|
eb5a2f |
return -1;
|
|
|
eb5a2f |
}
|
|
|
eb5a2f |
|
|
|
eb5a2f |
XBZRLE.current_buf = g_try_malloc(TARGET_PAGE_SIZE);
|
|
|
eb5a2f |
if (!XBZRLE.current_buf) {
|
|
|
eb5a2f |
- DPRINTF("Error allocating current_buf\n");
|
|
|
eb5a2f |
+ error_report("Error allocating current_buf");
|
|
|
eb5a2f |
g_free(XBZRLE.encoded_buf);
|
|
|
eb5a2f |
XBZRLE.encoded_buf = NULL;
|
|
|
eb5a2f |
return -1;
|
|
|
eb5a2f |
@@ -1110,6 +1110,7 @@ static SaveVMHandlers savevm_ram_handlers = {
|
|
|
eb5a2f |
|
|
|
eb5a2f |
void ram_mig_init(void)
|
|
|
eb5a2f |
{
|
|
|
eb5a2f |
+ qemu_mutex_init(&XBZRLE.lock);
|
|
|
eb5a2f |
register_savevm_live(NULL, "ram", 0, 4, &savevm_ram_handlers, NULL);
|
|
|
eb5a2f |
}
|
|
|
eb5a2f |
|
|
|
eb5a2f |
--
|
|
|
eb5a2f |
1.7.1
|
|
|
eb5a2f |
|