@@ -167,14 +167,16 @@ static struct {
/* Cache for XBZRLE, Protected by lock. */
PageCache *cache;
QemuMutex lock;
-} XBZRLE = {
- .encoded_buf = NULL,
- .current_buf = NULL,
- .cache = NULL,
-};
+} XBZRLE;
+
/* buffer used for XBZRLE decoding */
static uint8_t *xbzrle_decoded_buf;
+void XBZRLE_init(void)
+{
+ qemu_mutex_init(&XBZRLE.lock);
+}
+
static void XBZRLE_cache_lock(void)
{
if (migrate_use_xbzrle())
@@ -189,39 +191,35 @@ static void XBZRLE_cache_unlock(void)
int64_t xbzrle_cache_resize(int64_t new_size)
{
- PageCache *new_cache, *cache_to_free;
+ PageCache *new_cache;
+ int64_t ret;
if (new_size < TARGET_PAGE_SIZE) {
return -1;
}
- /* no need to lock, the current thread holds qemu big lock */
+ XBZRLE_cache_lock();
+
if (XBZRLE.cache != NULL) {
- /* check XBZRLE.cache again later */
if (pow2floor(new_size) == migrate_xbzrle_cache_size()) {
- return pow2floor(new_size);
+ goto out_new_size;
}
new_cache = cache_init(new_size / TARGET_PAGE_SIZE,
TARGET_PAGE_SIZE);
if (!new_cache) {
DPRINTF("Error creating cache\n");
- return -1;
+ goto out;
}
- XBZRLE_cache_lock();
- /* the XBZRLE.cache may have be destroyed, check it again */
- if (XBZRLE.cache != NULL) {
- cache_to_free = XBZRLE.cache;
- XBZRLE.cache = new_cache;
- } else {
- cache_to_free = new_cache;
- }
- XBZRLE_cache_unlock();
-
- cache_fini(cache_to_free);
+ cache_fini(XBZRLE.cache);
+ XBZRLE.cache = new_cache;
}
- return pow2floor(new_size);
+out_new_size:
+ ret = pow2floor(new_size);
+out:
+ XBZRLE_cache_unlock();
+ return ret;
}
/* accounting for migration statistics */
@@ -735,17 +733,16 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
dirty_rate_high_cnt = 0;
if (migrate_use_xbzrle()) {
- qemu_mutex_lock_iothread();
+ XBZRLE_cache_lock();
XBZRLE.cache = cache_init(migrate_xbzrle_cache_size() /
TARGET_PAGE_SIZE,
TARGET_PAGE_SIZE);
if (!XBZRLE.cache) {
- qemu_mutex_unlock_iothread();
+ XBZRLE_cache_unlock();
DPRINTF("Error creating cache\n");
return -1;
}
- qemu_mutex_init(&XBZRLE.lock);
- qemu_mutex_unlock_iothread();
+ XBZRLE_cache_unlock();
/* We prefer not to abort if there is no memory */
XBZRLE.encoded_buf = g_try_malloc0(TARGET_PAGE_SIZE);
@@ -26,6 +26,7 @@ enum {
extern const uint32_t arch_type;
+void XBZRLE_init(void);
void select_soundhw(const char *optarg);
void do_acpitable_option(const QemuOpts *opts);
void do_smbios_option(QemuOpts *opts);
@@ -3008,6 +3008,7 @@ int main(int argc, char **argv, char **envp)
qemu_init_auxval(envp);
qemu_cache_utils_init();
+ XBZRLE_init();
QLIST_INIT (&vm_change_state_head);
os_setup_early_signal_handling();