From: Peter Xu <peterx@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Avihai Horon" <avihaih@nvidia.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Daniel P . Berrangé" <berrange@redhat.com>,
"Leonardo Bras Soares Passos" <lsoaresp@redhat.com>,
"Juan Quintela" <quintela@redhat.com>,
peterx@redhat.com, "Laurent Vivier" <lvivier@redhat.com>,
"Thomas Huth" <thuth@redhat.com>
Subject: [PATCH RFC 2/3] Revert "tests/qtest: massively speed up migration-test"
Date: Thu, 1 Jun 2023 21:16:25 -0400 [thread overview]
Message-ID: <20230602011626.226640-3-peterx@redhat.com> (raw)
In-Reply-To: <20230602011626.226640-1-peterx@redhat.com>
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
next prev parent reply other threads:[~2023-06-02 1:17 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-02 1:16 [PATCH RFC 0/3] migration: switchover-hold flag Peter Xu
2023-06-02 1:16 ` [PATCH RFC 1/3] migration: switchover-hold parameter Peter Xu
2023-06-02 11:14 ` Daniel P. Berrangé
2023-06-02 13:20 ` Peter Xu
2023-06-02 1:16 ` Peter Xu [this message]
2023-06-02 1:16 ` [PATCH RFC 3/3] qtest/migration: Use switchover-hold to speedup Peter Xu
2023-06-02 11:03 ` Daniel P. Berrangé
2023-06-02 13:23 ` Peter Xu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230602011626.226640-3-peterx@redhat.com \
--to=peterx@redhat.com \
--cc=avihaih@nvidia.com \
--cc=berrange@redhat.com \
--cc=lsoaresp@redhat.com \
--cc=lvivier@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.com \
--cc=thuth@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.