This reverts commit e76a92b869f17d7a3f554890fb89b7da595dd652. --- tests/qtest/migration-test.c | 143 +++++------------------------------ 1 file changed, 18 insertions(+), 125 deletions(-)
diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index d2cd71e6cf..b0c355bbd9 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -46,20 +46,6 @@ static bool uffd_feature_thread_id; static bool got_src_stop; static bool got_dst_resume; -/* - * An initial 3 MB offset is used as that corresponds - * to ~1 sec of data transfer with our bandwidth setting. - */ -#define MAGIC_OFFSET_BASE (3 * 1024 * 1024) -/* - * A further 1k is added to ensure we're not a multiple - * of TEST_MEM_PAGE_SIZE, thus avoid clash with writes - * from the migration guest workload. - */ -#define MAGIC_OFFSET_SHUFFLE 1024 -#define MAGIC_OFFSET (MAGIC_OFFSET_BASE + MAGIC_OFFSET_SHUFFLE) -#define MAGIC_MARKER 0xFEED12345678CAFEULL - /* * Dirtylimit stop working if dirty page rate error * value less than DIRTYLIMIT_TOLERANCE_RANGE @@ -459,91 +445,6 @@ static void migrate_ensure_converge(QTestState *who) migrate_set_parameter_int(who, "downtime-limit", 30 * 1000); } -/* - * Our goal is to ensure that we run a single full migration - * iteration, and also dirty memory, ensuring that at least - * one further iteration is required. - * - * We can't directly synchronize with the start of a migration - * so we have to apply some tricks monitoring memory that is - * transferred. - * - * Initially we set the migration bandwidth to an insanely - * low value, with tiny max downtime too. This basically - * guarantees migration will never complete. - * - * This will result in a test that is unacceptably slow though, - * so we can't let the entire migration pass run at this speed. - * Our intent is to let it run just long enough that we can - * prove data prior to the marker has been transferred *AND* - * also prove this transferred data is dirty again. - * - * Before migration starts, we write a 64-bit magic marker - * into a fixed location in the src VM RAM. - * - * Then watch dst memory until the marker appears. This is - * proof that start_address -> MAGIC_OFFSET_BASE has been - * transferred. - * - * Finally we go back to the source and read a byte just - * before the marker untill we see it flip in value. This - * is proof that start_address -> MAGIC_OFFSET_BASE - * is now dirty again. - * - * IOW, we're guaranteed at least a 2nd migration pass - * at this point. - * - * We can now let migration run at full speed to finish - * the test - */ -static void migrate_prepare_for_dirty_mem(QTestState *from) -{ - /* - * The guest workflow iterates from start_address to - * end_address, writing 1 byte every TEST_MEM_PAGE_SIZE - * bytes. - * - * IOW, if we write to mem at a point which is NOT - * a multiple of TEST_MEM_PAGE_SIZE, our write won't - * conflict with the migration workflow. - * - * We put in a marker here, that we'll use to determine - * when the data has been transferred to the dst. - */ - qtest_writeq(from, start_address + MAGIC_OFFSET, MAGIC_MARKER); -} - -static void migrate_wait_for_dirty_mem(QTestState *from, - QTestState *to) -{ - uint64_t watch_address = start_address + MAGIC_OFFSET_BASE; - uint64_t marker_address = start_address + MAGIC_OFFSET; - uint8_t watch_byte; - - /* - * Wait for the MAGIC_MARKER to get transferred, as an - * indicator that a migration pass has made some known - * amount of progress. - */ - do { - usleep(1000 * 10); - } while (qtest_readq(to, marker_address) != MAGIC_MARKER); - - /* - * Now ensure that already transferred bytes are - * dirty again from the guest workload. Note the - * guest byte value will wrap around and by chance - * match the original watch_byte. This is harmless - * as we'll eventually see a different value if we - * keep watching - */ - watch_byte = qtest_readb(from, watch_address); - do { - usleep(1000 * 10); - } while (qtest_readb(from, watch_address) == watch_byte); -} - - static void migrate_pause(QTestState *who) { qtest_qmp_assert_success(who, "{ 'execute': 'migrate-pause' }"); @@ -676,10 +577,7 @@ typedef struct { MIG_TEST_FAIL_DEST_QUIT_ERR, } result; - /* - * Optional: set number of migration passes to wait for, if live==true. - * If zero, then merely wait for a few MB of dirty data - */ + /* Optional: set number of migration passes to wait for, if live==true */ unsigned int iterations; /* @@ -1267,14 +1165,12 @@ static int migrate_postcopy_prepare(QTestState **from_ptr, migrate_ensure_non_converge(from); - migrate_prepare_for_dirty_mem(from); - /* Wait for the first serial output from the source */ wait_for_serial("src_serial"); migrate_qmp(from, uri, "{}"); - migrate_wait_for_dirty_mem(from, to); + wait_for_migration_pass(from); *from_ptr = from; *to_ptr = to; @@ -1509,8 +1405,14 @@ static void test_precopy_common(MigrateCommon *args) } if (args->live) { + /* + * Testing live migration, we want to ensure that some + * memory is re-dirtied after being transferred, so that + * we exercise logic for dirty page handling. We achieve + * this with a ridiculosly low bandwidth that guarantees + * non-convergance. + */ migrate_ensure_non_converge(from); - migrate_prepare_for_dirty_mem(from); } else { /* * Testing non-live migration, we allow it to run at @@ -1545,16 +1447,13 @@ static void test_precopy_common(MigrateCommon *args) } } else { if (args->live) { - /* - * For initial iteration(s) we must do a full pass, - * but for the final iteration, we need only wait - * for some dirty mem before switching to converge - */ - while (args->iterations > 1) { + if (args->iterations) { + while (args->iterations--) { + wait_for_migration_pass(from); + } + } else { wait_for_migration_pass(from); - args->iterations--; } - migrate_wait_for_dirty_mem(from, to); migrate_ensure_converge(from); @@ -1687,9 +1586,6 @@ static void test_ignore_shared(void) return; } - migrate_ensure_non_converge(from); - migrate_prepare_for_dirty_mem(from); - migrate_set_capability(from, "x-ignore-shared", true); migrate_set_capability(to, "x-ignore-shared", true); @@ -1698,7 +1594,7 @@ static void test_ignore_shared(void) migrate_qmp(from, uri, "{}"); - migrate_wait_for_dirty_mem(from, to); + wait_for_migration_pass(from); if (!got_src_stop) { qtest_qmp_eventwait(from, "STOP"); @@ -2402,7 +2298,6 @@ static void test_multifd_tcp_cancel(void) } migrate_ensure_non_converge(from); - migrate_prepare_for_dirty_mem(from); migrate_set_parameter_int(from, "multifd-channels", 16); migrate_set_parameter_int(to, "multifd-channels", 16); @@ -2421,7 +2316,7 @@ static void test_multifd_tcp_cancel(void) migrate_qmp(from, uri, "{}"); - migrate_wait_for_dirty_mem(from, to); + wait_for_migration_pass(from); migrate_cancel(from); @@ -2450,13 +2345,11 @@ static void test_multifd_tcp_cancel(void) wait_for_migration_status(from, "cancelled", NULL); - migrate_ensure_non_converge(from); + migrate_ensure_converge(from); migrate_qmp(from, uri, "{}"); - migrate_wait_for_dirty_mem(from, to); - - migrate_ensure_converge(from); + wait_for_migration_pass(from); if (!got_src_stop) { qtest_qmp_eventwait(from, "STOP"); -- 2.40.1