* [Qemu-devel] [PULL 1/5] migration: introduce decompress-error-check
2018-06-04 4:21 [Qemu-devel] [PULL 0/5] Migration pull request Juan Quintela
@ 2018-06-04 4:21 ` Juan Quintela
2018-06-04 4:21 ` [Qemu-devel] [PULL 2/5] migration: discard non-migratable RAMBlocks Juan Quintela
` (5 subsequent siblings)
6 siblings, 0 replies; 20+ messages in thread
From: Juan Quintela @ 2018-06-04 4:21 UTC (permalink / raw)
To: qemu-devel; +Cc: dgilbert, lvivier, peterx, Xiao Guangrong
From: Xiao Guangrong <xiaoguangrong@tencent.com>
QEMU 3.0 enables strict check for compression & decompression to
make the migration more robust, that depends on the source to fix
the internal design which triggers the unexpected error conditions
To make it work for migrating old version QEMU to 2.13 QEMU, we
introduce this parameter to disable the error check on the
destination which is the default behavior of the machine type
which is older than 2.13, alternately, the strict check can be
enabled explicitly as followings:
-M pc-q35-2.11 -global migration.decompress-error-check=true
Signed-off-by: Xiao Guangrong <xiaoguangrong@tencent.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
hw/arm/virt.c | 4 ++++
hw/i386/pc_piix.c | 1 +
hw/i386/pc_q35.c | 1 +
include/hw/compat.h | 7 ++++++-
migration/migration.c | 4 ++++
migration/migration.h | 7 +++++++
migration/ram.c | 2 +-
7 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index a3a28e20e8..b2a67a4c00 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1693,6 +1693,9 @@ static void machvirt_machine_init(void)
}
type_init(machvirt_machine_init);
+#define VIRT_COMPAT_2_12 \
+ HW_COMPAT_2_12
+
static void virt_2_12_instance_init(Object *obj)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -1763,6 +1766,7 @@ static void virt_2_12_instance_init(Object *obj)
static void virt_machine_2_12_options(MachineClass *mc)
{
+ SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_12);
}
DEFINE_VIRT_MACHINE_AS_LATEST(2, 12)
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index b4c5b03274..3d81136065 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -430,6 +430,7 @@ static void pc_i440fx_3_0_machine_options(MachineClass *m)
pc_i440fx_machine_options(m);
m->alias = "pc";
m->is_default = 1;
+ SET_MACHINE_COMPAT(m, PC_COMPAT_2_12);
}
DEFINE_I440FX_MACHINE(v3_0, "pc-i440fx-3.0", NULL,
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 83d6d75efa..b60cbb9266 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -312,6 +312,7 @@ static void pc_q35_3_0_machine_options(MachineClass *m)
{
pc_q35_machine_options(m);
m->alias = "q35";
+ SET_MACHINE_COMPAT(m, PC_COMPAT_2_12);
}
DEFINE_Q35_MACHINE(v3_0, "pc-q35-3.0", NULL,
diff --git a/include/hw/compat.h b/include/hw/compat.h
index 4681c2719a..563908b874 100644
--- a/include/hw/compat.h
+++ b/include/hw/compat.h
@@ -1,7 +1,12 @@
#ifndef HW_COMPAT_H
#define HW_COMPAT_H
-#define HW_COMPAT_2_12
+#define HW_COMPAT_2_12 \
+ {\
+ .driver = "migration",\
+ .property = "decompress-error-check",\
+ .value = "off",\
+ },
#define HW_COMPAT_2_11 \
{\
diff --git a/migration/migration.c b/migration/migration.c
index 05aec2c905..a5384865ff 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2971,6 +2971,8 @@ void migration_global_dump(Monitor *mon)
ms->send_configuration ? "on" : "off");
monitor_printf(mon, "send-section-footer: %s\n",
ms->send_section_footer ? "on" : "off");
+ monitor_printf(mon, "decompress-error-check: %s\n",
+ ms->decompress_error_check ? "on" : "off");
}
#define DEFINE_PROP_MIG_CAP(name, x) \
@@ -2984,6 +2986,8 @@ static Property migration_properties[] = {
send_configuration, true),
DEFINE_PROP_BOOL("send-section-footer", MigrationState,
send_section_footer, true),
+ DEFINE_PROP_BOOL("decompress-error-check", MigrationState,
+ decompress_error_check, true),
/* Migration parameters */
DEFINE_PROP_UINT8("x-compress-level", MigrationState,
diff --git a/migration/migration.h b/migration/migration.h
index 8f0c82159b..5af57d616c 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -212,6 +212,13 @@ struct MigrationState
/* Needed by postcopy-pause state */
QemuSemaphore postcopy_pause_sem;
QemuSemaphore postcopy_pause_rp_sem;
+ /*
+ * Whether we abort the migration if decompression errors are
+ * detected at the destination. It is left at false for qemu
+ * older than 3.0, since only newer qemu sends streams that
+ * do not trigger spurious decompression errors.
+ */
+ bool decompress_error_check;
};
void migrate_set_state(int *state, int old_state, int new_state);
diff --git a/migration/ram.c b/migration/ram.c
index c53e8369a3..090187ca04 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -2881,7 +2881,7 @@ static void *do_data_decompress(void *opaque)
ret = qemu_uncompress_data(¶m->stream, des, pagesize,
param->compbuf, len);
- if (ret < 0) {
+ if (ret < 0 && migrate_get_current()->decompress_error_check) {
error_report("decompress data failed");
qemu_file_set_error(decomp_file, ret);
}
--
2.17.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PULL 2/5] migration: discard non-migratable RAMBlocks
2018-06-04 4:21 [Qemu-devel] [PULL 0/5] Migration pull request Juan Quintela
2018-06-04 4:21 ` [Qemu-devel] [PULL 1/5] migration: introduce decompress-error-check Juan Quintela
@ 2018-06-04 4:21 ` Juan Quintela
2018-06-04 4:21 ` [Qemu-devel] [PULL 3/5] migration: Don't activate block devices if using -S Juan Quintela
` (4 subsequent siblings)
6 siblings, 0 replies; 20+ messages in thread
From: Juan Quintela @ 2018-06-04 4:21 UTC (permalink / raw)
To: qemu-devel; +Cc: dgilbert, lvivier, peterx, Cédric Le Goater
From: Cédric Le Goater <clg@kaod.org>
On the POWER9 processor, the XIVE interrupt controller can control
interrupt sources using MMIO to trigger events, to EOI or to turn off
the sources. Priority management and interrupt acknowledgment is also
controlled by MMIO in the presenter sub-engine.
These MMIO regions are exposed to guests in QEMU with a set of 'ram
device' memory mappings, similarly to VFIO, and the VMAs are populated
dynamically with the appropriate pages using a fault handler.
But, these regions are an issue for migration. We need to discard the
associated RAMBlocks from the RAM state on the source VM and let the
destination VM rebuild the memory mappings on the new host in the
post_load() operation just before resuming the system.
To achieve this goal, the following introduces a new RAMBlock flag
RAM_MIGRATABLE which is updated in the vmstate_register_ram() and
vmstate_unregister_ram() routines. This flag is then used by the
migration to identify RAMBlocks to discard on the source. Some checks
are also performed on the destination to make sure nothing invalid was
sent.
This change impacts the boston, malta and jazz mips boards for which
migration compatibility is broken.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
exec.c | 38 ++++++++++++++++++++++++++++++++
include/exec/cpu-common.h | 4 ++++
migration/postcopy-ram.c | 12 +++++-----
migration/ram.c | 46 +++++++++++++++++++++++++++++----------
migration/savevm.c | 2 ++
5 files changed, 84 insertions(+), 18 deletions(-)
diff --git a/exec.c b/exec.c
index c30f905598..af90e914cf 100644
--- a/exec.c
+++ b/exec.c
@@ -104,6 +104,9 @@ static MemoryRegion io_mem_unassigned;
* (Set during postcopy)
*/
#define RAM_UF_ZEROPAGE (1 << 3)
+
+/* RAM can be migrated */
+#define RAM_MIGRATABLE (1 << 4)
#endif
#ifdef TARGET_PAGE_BITS_VARY
@@ -1838,6 +1841,21 @@ void qemu_ram_set_uf_zeroable(RAMBlock *rb)
rb->flags |= RAM_UF_ZEROPAGE;
}
+bool qemu_ram_is_migratable(RAMBlock *rb)
+{
+ return rb->flags & RAM_MIGRATABLE;
+}
+
+void qemu_ram_set_migratable(RAMBlock *rb)
+{
+ rb->flags |= RAM_MIGRATABLE;
+}
+
+void qemu_ram_unset_migratable(RAMBlock *rb)
+{
+ rb->flags &= ~RAM_MIGRATABLE;
+}
+
/* Called with iothread lock held. */
void qemu_ram_set_idstr(RAMBlock *new_block, const char *name, DeviceState *dev)
{
@@ -3893,6 +3911,26 @@ int qemu_ram_foreach_block(RAMBlockIterFunc func, void *opaque)
return ret;
}
+int qemu_ram_foreach_migratable_block(RAMBlockIterFunc func, void *opaque)
+{
+ RAMBlock *block;
+ int ret = 0;
+
+ rcu_read_lock();
+ RAMBLOCK_FOREACH(block) {
+ if (!qemu_ram_is_migratable(block)) {
+ continue;
+ }
+ ret = func(block->idstr, block->host, block->offset,
+ block->used_length, opaque);
+ if (ret) {
+ break;
+ }
+ }
+ rcu_read_unlock();
+ return ret;
+}
+
/*
* Unmap pages of memory from start to start+length such that
* they a) read as 0, b) Trigger whatever fault mechanism
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 24d335f95d..0b58e262f3 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -75,6 +75,9 @@ const char *qemu_ram_get_idstr(RAMBlock *rb);
bool qemu_ram_is_shared(RAMBlock *rb);
bool qemu_ram_is_uf_zeroable(RAMBlock *rb);
void qemu_ram_set_uf_zeroable(RAMBlock *rb);
+bool qemu_ram_is_migratable(RAMBlock *rb);
+void qemu_ram_set_migratable(RAMBlock *rb);
+void qemu_ram_unset_migratable(RAMBlock *rb);
size_t qemu_ram_pagesize(RAMBlock *block);
size_t qemu_ram_pagesize_largest(void);
@@ -119,6 +122,7 @@ typedef int (RAMBlockIterFunc)(const char *block_name, void *host_addr,
ram_addr_t offset, ram_addr_t length, void *opaque);
int qemu_ram_foreach_block(RAMBlockIterFunc func, void *opaque);
+int qemu_ram_foreach_migratable_block(RAMBlockIterFunc func, void *opaque);
int ram_block_discard_range(RAMBlock *rb, uint64_t start, size_t length);
#endif
diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index 658b750a8e..48e51556a7 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -374,7 +374,7 @@ bool postcopy_ram_supported_by_host(MigrationIncomingState *mis)
}
/* We don't support postcopy with shared RAM yet */
- if (qemu_ram_foreach_block(test_ramblock_postcopiable, NULL)) {
+ if (qemu_ram_foreach_migratable_block(test_ramblock_postcopiable, NULL)) {
goto out;
}
@@ -502,7 +502,7 @@ static int cleanup_range(const char *block_name, void *host_addr,
*/
int postcopy_ram_incoming_init(MigrationIncomingState *mis, size_t ram_pages)
{
- if (qemu_ram_foreach_block(init_range, NULL)) {
+ if (qemu_ram_foreach_migratable_block(init_range, NULL)) {
return -1;
}
@@ -524,7 +524,7 @@ int postcopy_ram_incoming_cleanup(MigrationIncomingState *mis)
return -1;
}
- if (qemu_ram_foreach_block(cleanup_range, mis)) {
+ if (qemu_ram_foreach_migratable_block(cleanup_range, mis)) {
return -1;
}
/* Let the fault thread quit */
@@ -593,7 +593,7 @@ static int nhp_range(const char *block_name, void *host_addr,
*/
int postcopy_ram_prepare_discard(MigrationIncomingState *mis)
{
- if (qemu_ram_foreach_block(nhp_range, mis)) {
+ if (qemu_ram_foreach_migratable_block(nhp_range, mis)) {
return -1;
}
@@ -604,7 +604,7 @@ int postcopy_ram_prepare_discard(MigrationIncomingState *mis)
/*
* Mark the given area of RAM as requiring notification to unwritten areas
- * Used as a callback on qemu_ram_foreach_block.
+ * Used as a callback on qemu_ram_foreach_migratable_block.
* host_addr: Base of area to mark
* offset: Offset in the whole ram arena
* length: Length of the section
@@ -1099,7 +1099,7 @@ int postcopy_ram_enable_notify(MigrationIncomingState *mis)
mis->have_fault_thread = true;
/* Mark so that we get notified of accesses to unwritten areas */
- if (qemu_ram_foreach_block(ram_block_enable_notify, mis)) {
+ if (qemu_ram_foreach_migratable_block(ram_block_enable_notify, mis)) {
return -1;
}
diff --git a/migration/ram.c b/migration/ram.c
index 090187ca04..290b281446 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -157,11 +157,16 @@ out:
return ret;
}
+/* Should be holding either ram_list.mutex, or the RCU lock. */
+#define RAMBLOCK_FOREACH_MIGRATABLE(block) \
+ RAMBLOCK_FOREACH(block) \
+ if (!qemu_ram_is_migratable(block)) {} else
+
static void ramblock_recv_map_init(void)
{
RAMBlock *rb;
- RAMBLOCK_FOREACH(rb) {
+ RAMBLOCK_FOREACH_MIGRATABLE(rb) {
assert(!rb->receivedmap);
rb->receivedmap = bitmap_new(rb->max_length >> qemu_target_page_bits());
}
@@ -1078,6 +1083,10 @@ unsigned long migration_bitmap_find_dirty(RAMState *rs, RAMBlock *rb,
unsigned long *bitmap = rb->bmap;
unsigned long next;
+ if (!qemu_ram_is_migratable(rb)) {
+ return size;
+ }
+
if (rs->ram_bulk_stage && start > 0) {
next = start + 1;
} else {
@@ -1123,7 +1132,7 @@ uint64_t ram_pagesize_summary(void)
RAMBlock *block;
uint64_t summary = 0;
- RAMBLOCK_FOREACH(block) {
+ RAMBLOCK_FOREACH_MIGRATABLE(block) {
summary |= block->page_size;
}
@@ -1147,7 +1156,7 @@ static void migration_bitmap_sync(RAMState *rs)
qemu_mutex_lock(&rs->bitmap_mutex);
rcu_read_lock();
- RAMBLOCK_FOREACH(block) {
+ RAMBLOCK_FOREACH_MIGRATABLE(block) {
migration_bitmap_sync_range(rs, block, 0, block->used_length);
}
rcu_read_unlock();
@@ -1786,6 +1795,11 @@ static int ram_save_host_page(RAMState *rs, PageSearchStatus *pss,
size_t pagesize_bits =
qemu_ram_pagesize(pss->block) >> TARGET_PAGE_BITS;
+ if (!qemu_ram_is_migratable(pss->block)) {
+ error_report("block %s should not be migrated !", pss->block->idstr);
+ return 0;
+ }
+
do {
/* Check the pages is dirty and if it is send it */
if (!migration_bitmap_clear_dirty(rs, pss->block, pss->page)) {
@@ -1884,7 +1898,7 @@ uint64_t ram_bytes_total(void)
uint64_t total = 0;
rcu_read_lock();
- RAMBLOCK_FOREACH(block) {
+ RAMBLOCK_FOREACH_MIGRATABLE(block) {
total += block->used_length;
}
rcu_read_unlock();
@@ -1939,7 +1953,7 @@ static void ram_save_cleanup(void *opaque)
*/
memory_global_dirty_log_stop();
- QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
+ RAMBLOCK_FOREACH_MIGRATABLE(block) {
g_free(block->bmap);
block->bmap = NULL;
g_free(block->unsentmap);
@@ -2002,7 +2016,7 @@ void ram_postcopy_migrated_memory_release(MigrationState *ms)
{
struct RAMBlock *block;
- RAMBLOCK_FOREACH(block) {
+ RAMBLOCK_FOREACH_MIGRATABLE(block) {
unsigned long *bitmap = block->bmap;
unsigned long range = block->used_length >> TARGET_PAGE_BITS;
unsigned long run_start = find_next_zero_bit(bitmap, range, 0);
@@ -2080,7 +2094,7 @@ static int postcopy_each_ram_send_discard(MigrationState *ms)
struct RAMBlock *block;
int ret;
- RAMBLOCK_FOREACH(block) {
+ RAMBLOCK_FOREACH_MIGRATABLE(block) {
PostcopyDiscardState *pds =
postcopy_discard_send_init(ms, block->idstr);
@@ -2288,7 +2302,7 @@ int ram_postcopy_send_discard_bitmap(MigrationState *ms)
rs->last_sent_block = NULL;
rs->last_page = 0;
- QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
+ RAMBLOCK_FOREACH_MIGRATABLE(block) {
unsigned long pages = block->used_length >> TARGET_PAGE_BITS;
unsigned long *bitmap = block->bmap;
unsigned long *unsentmap = block->unsentmap;
@@ -2447,7 +2461,7 @@ static void ram_list_init_bitmaps(void)
/* Skip setting bitmap if there is no RAM */
if (ram_bytes_total()) {
- QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
+ RAMBLOCK_FOREACH_MIGRATABLE(block) {
pages = block->max_length >> TARGET_PAGE_BITS;
block->bmap = bitmap_new(pages);
bitmap_set(block->bmap, 0, pages);
@@ -2563,7 +2577,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE);
- RAMBLOCK_FOREACH(block) {
+ RAMBLOCK_FOREACH_MIGRATABLE(block) {
qemu_put_byte(f, strlen(block->idstr));
qemu_put_buffer(f, (uint8_t *)block->idstr, strlen(block->idstr));
qemu_put_be64(f, block->used_length);
@@ -2807,6 +2821,11 @@ static inline RAMBlock *ram_block_from_stream(QEMUFile *f, int flags)
return NULL;
}
+ if (!qemu_ram_is_migratable(block)) {
+ error_report("block %s should not be migrated !", id);
+ return NULL;
+ }
+
return block;
}
@@ -3049,7 +3068,7 @@ static int ram_load_cleanup(void *opaque)
xbzrle_load_cleanup();
compress_threads_load_cleanup();
- RAMBLOCK_FOREACH(rb) {
+ RAMBLOCK_FOREACH_MIGRATABLE(rb) {
g_free(rb->receivedmap);
rb->receivedmap = NULL;
}
@@ -3311,7 +3330,10 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
length = qemu_get_be64(f);
block = qemu_ram_block_by_name(id);
- if (block) {
+ if (block && !qemu_ram_is_migratable(block)) {
+ error_report("block %s should not be migrated !", id);
+ ret = -EINVAL;
+ } else if (block) {
if (length != block->used_length) {
Error *local_err = NULL;
diff --git a/migration/savevm.c b/migration/savevm.c
index 4251125831..a68a9ac635 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2688,11 +2688,13 @@ void vmstate_register_ram(MemoryRegion *mr, DeviceState *dev)
{
qemu_ram_set_idstr(mr->ram_block,
memory_region_name(mr), dev);
+ qemu_ram_set_migratable(mr->ram_block);
}
void vmstate_unregister_ram(MemoryRegion *mr, DeviceState *dev)
{
qemu_ram_unset_idstr(mr->ram_block);
+ qemu_ram_unset_migratable(mr->ram_block);
}
void vmstate_register_ram_global(MemoryRegion *mr)
--
2.17.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PULL 3/5] migration: Don't activate block devices if using -S
2018-06-04 4:21 [Qemu-devel] [PULL 0/5] Migration pull request Juan Quintela
2018-06-04 4:21 ` [Qemu-devel] [PULL 1/5] migration: introduce decompress-error-check Juan Quintela
2018-06-04 4:21 ` [Qemu-devel] [PULL 2/5] migration: discard non-migratable RAMBlocks Juan Quintela
@ 2018-06-04 4:21 ` Juan Quintela
2018-06-04 4:21 ` [Qemu-devel] [PULL 4/5] migration: remove unnecessary variables len in QIOChannelRDMA Juan Quintela
` (3 subsequent siblings)
6 siblings, 0 replies; 20+ messages in thread
From: Juan Quintela @ 2018-06-04 4:21 UTC (permalink / raw)
To: qemu-devel; +Cc: dgilbert, lvivier, peterx
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Activating the block devices causes the locks to be taken on
the backing file. If we're running with -S and the destination libvirt
hasn't started the destination with 'cont', it's expecting the locks are
still untaken.
Don't activate the block devices if we're not going to autostart the VM;
'cont' already will do that anyway. This change is tied to the new
migration capability 'late-block-activate' that defaults to off, keeping
the old behaviour by default.
bz: https://bugzilla.redhat.com/show_bug.cgi?id=1560854
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
migration/migration.c | 34 +++++++++++++++++++++++++++-------
qapi/migration.json | 6 +++++-
2 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index a5384865ff..1e99ec9b7e 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -202,6 +202,16 @@ static void migrate_generate_event(int new_state)
}
}
+static bool migrate_late_block_activate(void)
+{
+ MigrationState *s;
+
+ s = migrate_get_current();
+
+ return s->enabled_capabilities[
+ MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE];
+}
+
/*
* Called on -incoming with a defer: uri.
* The migration can be started later after any parameters have been
@@ -311,13 +321,23 @@ static void process_incoming_migration_bh(void *opaque)
Error *local_err = NULL;
MigrationIncomingState *mis = opaque;
- /* Make sure all file formats flush their mutable metadata.
- * If we get an error here, just don't restart the VM yet. */
- bdrv_invalidate_cache_all(&local_err);
- if (local_err) {
- error_report_err(local_err);
- local_err = NULL;
- autostart = false;
+ /* If capability late_block_activate is set:
+ * Only fire up the block code now if we're going to restart the
+ * VM, else 'cont' will do it.
+ * This causes file locking to happen; so we don't want it to happen
+ * unless we really are starting the VM.
+ */
+ if (!migrate_late_block_activate() ||
+ (autostart && (!global_state_received() ||
+ global_state_get_runstate() == RUN_STATE_RUNNING))) {
+ /* Make sure all file formats flush their mutable metadata.
+ * If we get an error here, just don't restart the VM yet. */
+ bdrv_invalidate_cache_all(&local_err);
+ if (local_err) {
+ error_report_err(local_err);
+ local_err = NULL;
+ autostart = false;
+ }
}
/*
diff --git a/qapi/migration.json b/qapi/migration.json
index dc9cc85545..f7e10ee90f 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -376,13 +376,17 @@
# @postcopy-blocktime: Calculate downtime for postcopy live migration
# (since 3.0)
#
+# @late-block-activate: If enabled, the destination will not activate block
+# devices (and thus take locks) immediately at the end of migration.
+# (since 3.0)
+#
# Since: 1.2
##
{ 'enum': 'MigrationCapability',
'data': ['xbzrle', 'rdma-pin-all', 'auto-converge', 'zero-blocks',
'compress', 'events', 'postcopy-ram', 'x-colo', 'release-ram',
'block', 'return-path', 'pause-before-switchover', 'x-multifd',
- 'dirty-bitmaps', 'postcopy-blocktime' ] }
+ 'dirty-bitmaps', 'postcopy-blocktime', 'late-block-activate' ] }
##
# @MigrationCapabilityStatus:
--
2.17.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PULL 4/5] migration: remove unnecessary variables len in QIOChannelRDMA
2018-06-04 4:21 [Qemu-devel] [PULL 0/5] Migration pull request Juan Quintela
` (2 preceding siblings ...)
2018-06-04 4:21 ` [Qemu-devel] [PULL 3/5] migration: Don't activate block devices if using -S Juan Quintela
@ 2018-06-04 4:21 ` Juan Quintela
2018-06-04 4:21 ` [Qemu-devel] [PULL 5/5] migration: not wait RDMA_CM_EVENT_DISCONNECTED event after rdma_disconnect Juan Quintela
` (2 subsequent siblings)
6 siblings, 0 replies; 20+ messages in thread
From: Juan Quintela @ 2018-06-04 4:21 UTC (permalink / raw)
To: qemu-devel; +Cc: dgilbert, lvivier, peterx, Lidong Chen, Lidong Chen
From: Lidong Chen <jemmy858585@gmail.com>
Because qio_channel_rdma_writev and qio_channel_rdma_readv maybe invoked
by different threads concurrently, this patch removes unnecessary variables
len in QIOChannelRDMA and use local variable instead.
Signed-off-by: Lidong Chen <lidongchen@tencent.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Lidong Chen <jemmy858585@gmail.com>
---
migration/rdma.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/migration/rdma.c b/migration/rdma.c
index 7d233b0820..60779221b1 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -400,7 +400,6 @@ struct QIOChannelRDMA {
QIOChannel parent;
RDMAContext *rdma;
QEMUFile *file;
- size_t len;
bool blocking; /* XXX we don't actually honour this yet */
};
@@ -2608,6 +2607,7 @@ static ssize_t qio_channel_rdma_writev(QIOChannel *ioc,
int ret;
ssize_t done = 0;
size_t i;
+ size_t len = 0;
CHECK_ERROR_STATE();
@@ -2627,10 +2627,10 @@ static ssize_t qio_channel_rdma_writev(QIOChannel *ioc,
while (remaining) {
RDMAControlHeader head;
- rioc->len = MIN(remaining, RDMA_SEND_INCREMENT);
- remaining -= rioc->len;
+ len = MIN(remaining, RDMA_SEND_INCREMENT);
+ remaining -= len;
- head.len = rioc->len;
+ head.len = len;
head.type = RDMA_CONTROL_QEMU_FILE;
ret = qemu_rdma_exchange_send(rdma, &head, data, NULL, NULL, NULL);
@@ -2640,8 +2640,8 @@ static ssize_t qio_channel_rdma_writev(QIOChannel *ioc,
return ret;
}
- data += rioc->len;
- done += rioc->len;
+ data += len;
+ done += len;
}
}
@@ -2736,8 +2736,7 @@ static ssize_t qio_channel_rdma_readv(QIOChannel *ioc,
}
}
}
- rioc->len = done;
- return rioc->len;
+ return done;
}
/*
--
2.17.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PULL 5/5] migration: not wait RDMA_CM_EVENT_DISCONNECTED event after rdma_disconnect
2018-06-04 4:21 [Qemu-devel] [PULL 0/5] Migration pull request Juan Quintela
` (3 preceding siblings ...)
2018-06-04 4:21 ` [Qemu-devel] [PULL 4/5] migration: remove unnecessary variables len in QIOChannelRDMA Juan Quintela
@ 2018-06-04 4:21 ` Juan Quintela
2018-06-04 4:29 ` [Qemu-devel] [PULL 0/5] Migration pull request no-reply
2018-06-04 13:24 ` Peter Maydell
6 siblings, 0 replies; 20+ messages in thread
From: Juan Quintela @ 2018-06-04 4:21 UTC (permalink / raw)
To: qemu-devel; +Cc: dgilbert, lvivier, peterx, Lidong Chen, Lidong Chen
From: Lidong Chen <jemmy858585@gmail.com>
When cancel migration during RDMA precopy, the source qemu main thread hangs sometime.
The backtrace is:
(gdb) bt
#0 0x00007f249eabd43d in write () from /lib64/libpthread.so.0
#1 0x00007f24a1ce98e4 in rdma_get_cm_event (channel=0x4675d10, event=0x7ffe2f643dd0) at src/cma.c:2189
#2 0x00000000007b6166 in qemu_rdma_cleanup (rdma=0x6784000) at migration/rdma.c:2296
#3 0x00000000007b7cae in qio_channel_rdma_close (ioc=0x3bfcc30, errp=0x0) at migration/rdma.c:2999
#4 0x00000000008db60e in qio_channel_close (ioc=0x3bfcc30, errp=0x0) at io/channel.c:273
#5 0x00000000007a8765 in channel_close (opaque=0x3bfcc30) at migration/qemu-file-channel.c:98
#6 0x00000000007a71f9 in qemu_fclose (f=0x527c000) at migration/qemu-file.c:334
#7 0x0000000000795b96 in migrate_fd_cleanup (opaque=0x3b46280) at migration/migration.c:1162
#8 0x000000000093a71b in aio_bh_call (bh=0x3db7a20) at util/async.c:90
#9 0x000000000093a7b2 in aio_bh_poll (ctx=0x3b121c0) at util/async.c:118
#10 0x000000000093f2ad in aio_dispatch (ctx=0x3b121c0) at util/aio-posix.c:436
#11 0x000000000093ab41 in aio_ctx_dispatch (source=0x3b121c0, callback=0x0, user_data=0x0)
at util/async.c:261
#12 0x00007f249f73c7aa in g_main_context_dispatch () from /lib64/libglib-2.0.so.0
#13 0x000000000093dc5e in glib_pollfds_poll () at util/main-loop.c:215
#14 0x000000000093dd4e in os_host_main_loop_wait (timeout=28000000) at util/main-loop.c:263
#15 0x000000000093de05 in main_loop_wait (nonblocking=0) at util/main-loop.c:522
#16 0x00000000005bc6a5 in main_loop () at vl.c:1944
#17 0x00000000005c39b5 in main (argc=56, argv=0x7ffe2f6443f8, envp=0x3ad0030) at vl.c:4752
It does not get the RDMA_CM_EVENT_DISCONNECTED event after rdma_disconnect sometime.
According to IB Spec once active side send DREQ message, it should wait for DREP message
and only once it arrived it should trigger a DISCONNECT event. DREP message can be dropped
due to network issues.
For that case the spec defines a DREP_timeout state in the CM state machine, if the DREP is
dropped we should get a timeout and a TIMEWAIT_EXIT event will be trigger.
Unfortunately the current kernel CM implementation doesn't include the DREP_timeout state
and in above scenario we will not get DISCONNECT or TIMEWAIT_EXIT events.
So it should not invoke rdma_get_cm_event which may hang forever, and the event channel
is also destroyed in qemu_rdma_cleanup.
Signed-off-by: Lidong Chen <lidongchen@tencent.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
migration/rdma.c | 12 ++----------
migration/trace-events | 1 -
2 files changed, 2 insertions(+), 11 deletions(-)
diff --git a/migration/rdma.c b/migration/rdma.c
index 60779221b1..05aee3d591 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -2267,8 +2267,7 @@ static int qemu_rdma_write(QEMUFile *f, RDMAContext *rdma,
static void qemu_rdma_cleanup(RDMAContext *rdma)
{
- struct rdma_cm_event *cm_event;
- int ret, idx;
+ int idx;
if (rdma->cm_id && rdma->connected) {
if ((rdma->error_state ||
@@ -2282,14 +2281,7 @@ static void qemu_rdma_cleanup(RDMAContext *rdma)
qemu_rdma_post_send_control(rdma, NULL, &head);
}
- ret = rdma_disconnect(rdma->cm_id);
- if (!ret) {
- trace_qemu_rdma_cleanup_waiting_for_disconnect();
- ret = rdma_get_cm_event(rdma->channel, &cm_event);
- if (!ret) {
- rdma_ack_cm_event(cm_event);
- }
- }
+ rdma_disconnect(rdma->cm_id);
trace_qemu_rdma_cleanup_disconnect();
rdma->connected = false;
}
diff --git a/migration/trace-events b/migration/trace-events
index 3c798ddd11..4a768eaaeb 100644
--- a/migration/trace-events
+++ b/migration/trace-events
@@ -146,7 +146,6 @@ qemu_rdma_accept_pin_state(bool pin) "%d"
qemu_rdma_accept_pin_verbsc(void *verbs) "Verbs context after listen: %p"
qemu_rdma_block_for_wrid_miss(const char *wcompstr, int wcomp, const char *gcompstr, uint64_t req) "A Wanted wrid %s (%d) but got %s (%" PRIu64 ")"
qemu_rdma_cleanup_disconnect(void) ""
-qemu_rdma_cleanup_waiting_for_disconnect(void) ""
qemu_rdma_close(void) ""
qemu_rdma_connect_pin_all_requested(void) ""
qemu_rdma_connect_pin_all_outcome(bool pin) "%d"
--
2.17.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [PULL 0/5] Migration pull request
2018-06-04 4:21 [Qemu-devel] [PULL 0/5] Migration pull request Juan Quintela
` (4 preceding siblings ...)
2018-06-04 4:21 ` [Qemu-devel] [PULL 5/5] migration: not wait RDMA_CM_EVENT_DISCONNECTED event after rdma_disconnect Juan Quintela
@ 2018-06-04 4:29 ` no-reply
2018-06-04 7:30 ` Juan Quintela
2018-06-04 13:24 ` Peter Maydell
6 siblings, 1 reply; 20+ messages in thread
From: no-reply @ 2018-06-04 4:29 UTC (permalink / raw)
To: quintela; +Cc: famz, qemu-devel, lvivier, dgilbert, peterx
Hi,
This series seems to have some coding style problems. See output below for
more information:
Type: series
Message-id: 20180604042156.13812-1-quintela@redhat.com
Subject: [Qemu-devel] [PULL 0/5] Migration pull request
=== TEST SCRIPT BEGIN ===
#!/bin/bash
BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done
exit $failed
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
t [tag update] patchew/20180514065700.22202-1-clg@kaod.org -> patchew/20180514065700.22202-1-clg@kaod.org
* [new tag] patchew/20180604042156.13812-1-quintela@redhat.com -> patchew/20180604042156.13812-1-quintela@redhat.com
Switched to a new branch 'test'
99ac0fb20d migration: not wait RDMA_CM_EVENT_DISCONNECTED event after rdma_disconnect
7c902253bb migration: remove unnecessary variables len in QIOChannelRDMA
3c1203cb38 migration: Don't activate block devices if using -S
2ecc458546 migration: discard non-migratable RAMBlocks
718b388d4e migration: introduce decompress-error-check
=== OUTPUT BEGIN ===
Checking PATCH 1/5: migration: introduce decompress-error-check...
Checking PATCH 2/5: migration: discard non-migratable RAMBlocks...
ERROR: Macros with multiple statements should be enclosed in a do - while loop
#191: FILE: migration/ram.c:161:
+#define RAMBLOCK_FOREACH_MIGRATABLE(block) \
+ RAMBLOCK_FOREACH(block) \
+ if (!qemu_ram_is_migratable(block)) {} else
ERROR: trailing statements should be on next line
#193: FILE: migration/ram.c:163:
+ if (!qemu_ram_is_migratable(block)) {} else
total: 2 errors, 0 warnings, 273 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 3/5: migration: Don't activate block devices if using -S...
Checking PATCH 4/5: migration: remove unnecessary variables len in QIOChannelRDMA...
Checking PATCH 5/5: migration: not wait RDMA_CM_EVENT_DISCONNECTED event after rdma_disconnect...
=== OUTPUT END ===
Test command exited with code: 1
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [PULL 0/5] Migration pull request
2018-06-04 4:29 ` [Qemu-devel] [PULL 0/5] Migration pull request no-reply
@ 2018-06-04 7:30 ` Juan Quintela
0 siblings, 0 replies; 20+ messages in thread
From: Juan Quintela @ 2018-06-04 7:30 UTC (permalink / raw)
To: no-reply; +Cc: qemu-devel, famz, lvivier, dgilbert, peterx
no-reply@patchew.org wrote:
> Hi,
>
> This series seems to have some coding style problems. See output below for
> more information:
>
> Type: series
> Message-id: 20180604042156.13812-1-quintela@redhat.com
> Subject: [Qemu-devel] [PULL 0/5] Migration pull request
> Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
> From https://github.com/patchew-project/qemu
> t [tag update] patchew/20180514065700.22202-1-clg@kaod.org -> patchew/20180514065700.22202-1-clg@kaod.org
> * [new tag] patchew/20180604042156.13812-1-quintela@redhat.com -> patchew/20180604042156.13812-1-quintela@redhat.com
> Switched to a new branch 'test'
> 99ac0fb20d migration: not wait RDMA_CM_EVENT_DISCONNECTED event after rdma_disconnect
> 7c902253bb migration: remove unnecessary variables len in QIOChannelRDMA
> 3c1203cb38 migration: Don't activate block devices if using -S
> 2ecc458546 migration: discard non-migratable RAMBlocks
> 718b388d4e migration: introduce decompress-error-check
>
> === OUTPUT BEGIN ===
> Checking PATCH 1/5: migration: introduce decompress-error-check...
> Checking PATCH 2/5: migration: discard non-migratable RAMBlocks...
> ERROR: Macros with multiple statements should be enclosed in a do - while loop
> #191: FILE: migration/ram.c:161:
> +#define RAMBLOCK_FOREACH_MIGRATABLE(block) \
> + RAMBLOCK_FOREACH(block) \
> + if (!qemu_ram_is_migratable(block)) {} else
>
> ERROR: trailing statements should be on next line
> #193: FILE: migration/ram.c:163:
> + if (!qemu_ram_is_migratable(block)) {} else
We know. it is on purpose. There is no good solution. Changing
checkpatch don't make sense either, it is an one-off case.
Later, Juan.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [PULL 0/5] Migration pull request
2018-06-04 4:21 [Qemu-devel] [PULL 0/5] Migration pull request Juan Quintela
` (5 preceding siblings ...)
2018-06-04 4:29 ` [Qemu-devel] [PULL 0/5] Migration pull request no-reply
@ 2018-06-04 13:24 ` Peter Maydell
6 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2018-06-04 13:24 UTC (permalink / raw)
To: Juan Quintela
Cc: QEMU Developers, Laurent Vivier, Dr. David Alan Gilbert, Peter Xu
On 4 June 2018 at 05:21, Juan Quintela <quintela@redhat.com> wrote:
> The following changes since commit 392fba9f583223786f844dce9b2e7f9a0ce0147a:
>
> Merge remote-tracking branch 'remotes/stsquad/tags/pull-travis-updates-010618-1' into staging (2018-06-01 17:32:30 +0100)
>
> are available in the Git repository at:
>
> git://github.com/juanquintela/qemu.git tags/migration/20180604
>
> for you to fetch changes up to c5e76115ccb4979cec795a8ae38becd07c2fde9f:
>
> migration: not wait RDMA_CM_EVENT_DISCONNECTED event after rdma_disconnect (2018-06-04 05:46:15 +0200)
>
> ----------------------------------------------------------------
> migration/next for 20180604
>
> - RDMA fixes from (lidong)
> - Fix docempress-error-check (Xiao)
> - make -S and block work better (dave)
> - don't migrate "bad" ramblocks (Cédric)
>
> Please apply, Juan.
>
> ----------------------------------------------------------------
Applied, thanks.
-- PMM
^ permalink raw reply [flat|nested] 20+ messages in thread