1
From: Prasad Pandit <pjp@fedoraproject.org>
1
From: Prasad Pandit <pjp@fedoraproject.org>
2
2
3
Hello,
3
Hello,
4
4
5
* This series (v6) shuts down Multifd threads before starting Postcopy
6
migration. It helps to avoid an issue of multifd pages arriving late
7
at the destination during Postcopy phase and corrupting the vCPU
8
state. It also reorders the qtest patches and does some refactoring
9
changes as suggested in previous review.
10
===
11
67/67 qemu:qtest+qtest-x86_64 / qtest-x86_64/migration-test OK 161.35s 73 subtests passed
12
===
13
14
15
v5: https://lore.kernel.org/qemu-devel/20250205122712.229151-1-ppandit@redhat.com/T/#t
16
* This series (v5) consolidates migration capabilities setting in one
17
'set_migration_capabilities()' function, thus simplifying test sources.
18
It passes all migration tests.
19
===
20
66/66 qemu:qtest+qtest-x86_64 / qtest-x86_64/migration-test OK 143.66s 71 subtests passed
21
===
22
23
24
v4: https://lore.kernel.org/qemu-devel/20250127120823.144949-1-ppandit@redhat.com/T/#t
25
* This series (v4) adds more 'multifd+postcopy' qtests which test
26
Precopy migration with 'postcopy-ram' attribute set. And run
27
Postcopy migrations with 'multifd' channels enabled.
28
===
29
$ ../qtest/migration-test --tap -k -r '/x86_64/migration/multifd+postcopy' | grep -i 'slow test'
30
# slow test /x86_64/migration/multifd+postcopy/plain executed in 1.29 secs
31
# slow test /x86_64/migration/multifd+postcopy/recovery/tls/psk executed in 2.48 secs
32
# slow test /x86_64/migration/multifd+postcopy/preempt/plain executed in 1.49 secs
33
# slow test /x86_64/migration/multifd+postcopy/preempt/recovery/tls/psk executed in 2.52 secs
34
# slow test /x86_64/migration/multifd+postcopy/tcp/tls/psk/match executed in 3.62 secs
35
# slow test /x86_64/migration/multifd+postcopy/tcp/plain/zstd executed in 1.34 secs
36
# slow test /x86_64/migration/multifd+postcopy/tcp/plain/cancel executed in 2.24 secs
37
...
38
66/66 qemu:qtest+qtest-x86_64 / qtest-x86_64/migration-test OK 148.41s 71 subtests passed
39
===
40
41
42
v3: https://lore.kernel.org/qemu-devel/20250121131032.1611245-1-ppandit@redhat.com/T/#t
43
* This series (v3) passes all existing 'tests/qtest/migration/*' tests
44
and adds a new one to enable multifd channels with postcopy migration.
45
46
47
v2: https://lore.kernel.org/qemu-devel/20241129122256.96778-1-ppandit@redhat.com/T/#u
48
* This series (v2) further refactors the 'ram_save_target_page'
49
function to make it independent of the multifd & postcopy change.
50
51
52
v1: https://lore.kernel.org/qemu-devel/20241126115748.118683-1-ppandit@redhat.com/T/#u
53
* This series removes magic value (4-bytes) introduced in the
54
previous series for the Postcopy channel.
55
56
57
v0: https://lore.kernel.org/qemu-devel/20241029150908.1136894-1-ppandit@redhat.com/T/#u
5
* Currently Multifd and Postcopy migration can not be used together.
58
* Currently Multifd and Postcopy migration can not be used together.
6
QEMU shows "Postcopy is not yet compatible with multifd" message.
59
QEMU shows "Postcopy is not yet compatible with multifd" message.
7
60
8
When migrating guests with large (100's GB) RAM, Multifd threads
61
When migrating guests with large (100's GB) RAM, Multifd threads
9
help to accelerate migration, but inability to use it with the
62
help to accelerate migration, but inability to use it with the
...
...
13
migration together. Precopy and Multifd threads work during
66
migration together. Precopy and Multifd threads work during
14
the initial guest (RAM) transfer. When migration moves to the
67
the initial guest (RAM) transfer. When migration moves to the
15
Postcopy phase, Multifd threads are restrained and the Postcopy
68
Postcopy phase, Multifd threads are restrained and the Postcopy
16
threads start to request pages from the source side.
69
threads start to request pages from the source side.
17
70
18
* This series removes magic value (4-bytes) introduced in the
71
* This series introduces magic value (4-bytes) to be sent on the
19
previous series for the Postcopy channel. And refactoring of
72
Postcopy channel. It helps to differentiate channels and properly
20
the 'ram_save_target_page' function is made independent of
73
setup incoming connections on the destination side.
21
the multifd & postcopy change.
22
23
* This series passes all existing 'tests/qtest/migration/*' test
24
cases and adds a new one to enable multifd channels with postcopy
25
migration.
26
27
v2: https://lore.kernel.org/qemu-devel/20241129122256.96778-1-ppandit@redhat.com/T/#u
28
v1: https://lore.kernel.org/qemu-devel/20241126115748.118683-1-ppandit@redhat.com/T/#u
29
v0: https://lore.kernel.org/qemu-devel/20241029150908.1136894-1-ppandit@redhat.com/T/#u
30
74
31
75
32
Thank you.
76
Thank you.
33
---
77
---
34
Prasad Pandit (4):
78
Prasad Pandit (4):
35
migration/multifd: move macros to multifd header
79
migration/multifd: move macros to multifd header
36
migration: refactor ram_save_target_page functions
37
migration: enable multifd and postcopy together
80
migration: enable multifd and postcopy together
38
tests/qtest/migration: add postcopy test with multifd
81
tests/qtest/migration: consolidate set capabilities
82
tests/qtest/migration: add postcopy tests with multifd
39
83
40
migration/migration.c | 106 +++++++++++++++----------
84
migration/migration.c | 107 ++++++++++++----------
41
migration/multifd-nocomp.c | 3 +-
85
migration/multifd-nocomp.c | 3 +-
42
migration/multifd.c | 5 --
86
migration/multifd.c | 9 +-
43
migration/multifd.h | 5 ++
87
migration/multifd.h | 5 +
44
migration/options.c | 5 --
88
migration/options.c | 5 -
45
migration/ram.c | 69 +++++-----------
89
migration/ram.c | 7 +-
46
tests/qtest/migration/framework.c | 8 ++
90
tests/qtest/migration/compression-tests.c | 23 ++++-
47
tests/qtest/migration/framework.h | 3 +
91
tests/qtest/migration/cpr-tests.c | 4 +-
48
tests/qtest/migration/postcopy-tests.c | 10 +++
92
tests/qtest/migration/file-tests.c | 44 +++------
49
9 files changed, 112 insertions(+), 102 deletions(-)
93
tests/qtest/migration/framework.c | 58 +++++++++---
94
tests/qtest/migration/framework.h | 4 +-
95
tests/qtest/migration/postcopy-tests.c | 27 +++++-
96
tests/qtest/migration/precopy-tests.c | 38 +++++---
97
tests/qtest/migration/tls-tests.c | 51 ++++++++++-
98
14 files changed, 247 insertions(+), 138 deletions(-)
50
99
51
--
100
--
52
2.48.1
101
2.48.1
diff view generated by jsdifflib
1
From: Prasad Pandit <pjp@fedoraproject.org>
1
From: Prasad Pandit <pjp@fedoraproject.org>
2
2
3
Move MULTIFD_ macros to the header file so that
3
Move MULTIFD_ macros to the header file so that
4
they are accessible from other source files.
4
they are accessible from other source files.
5
5
6
Reviewed-by: Fabiano Rosas <farosas@suse.de>
6
Signed-off-by: Prasad Pandit <pjp@fedoraproject.org>
7
Signed-off-by: Prasad Pandit <pjp@fedoraproject.org>
7
---
8
---
8
migration/multifd.c | 5 -----
9
migration/multifd.c | 5 -----
9
migration/multifd.h | 5 +++++
10
migration/multifd.h | 5 +++++
10
2 files changed, 5 insertions(+), 5 deletions(-)
11
2 files changed, 5 insertions(+), 5 deletions(-)
11
12
12
v2:
13
v5: no change
13
- https://lore.kernel.org/qemu-devel/20241129122256.96778-1-ppandit@redhat.com/
14
- https://lore.kernel.org/qemu-devel/20250205122712.229151-1-ppandit@redhat.com/T/#t
14
15
15
diff --git a/migration/multifd.c b/migration/multifd.c
16
diff --git a/migration/multifd.c b/migration/multifd.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/migration/multifd.c
18
--- a/migration/multifd.c
18
+++ b/migration/multifd.c
19
+++ b/migration/multifd.c
...
...
42
+#define MULTIFD_VERSION 1
43
+#define MULTIFD_VERSION 1
43
+
44
+
44
/* Multifd Compression flags */
45
/* Multifd Compression flags */
45
#define MULTIFD_FLAG_SYNC (1 << 0)
46
#define MULTIFD_FLAG_SYNC (1 << 0)
46
47
47
--
48
--
48
2.48.1
49
2.48.1
diff view generated by jsdifflib
...
...
7
channels.
7
channels.
8
8
9
The Precopy and Multifd threads work during the
9
The Precopy and Multifd threads work during the
10
initial guest RAM transfer. When migration moves
10
initial guest RAM transfer. When migration moves
11
to the Postcopy phase, the multifd threads are
11
to the Postcopy phase, the multifd threads are
12
restrained and Postcopy threads on the destination
12
shutdown and Postcopy threads on the destination
13
request/pull data from the source side.
13
request/pull data from the source side.
14
14
15
Signed-off-by: Prasad Pandit <pjp@fedoraproject.org>
15
Signed-off-by: Prasad Pandit <pjp@fedoraproject.org>
16
---
16
---
17
migration/migration.c | 106 +++++++++++++++++++++++--------------
17
migration/migration.c | 107 ++++++++++++++++++++-----------------
18
migration/multifd-nocomp.c | 3 +-
18
migration/multifd-nocomp.c | 3 +-
19
migration/multifd.c | 4 +-
19
migration/options.c | 5 --
20
migration/options.c | 5 --
20
migration/ram.c | 4 +-
21
migration/ram.c | 7 ++-
21
4 files changed, 70 insertions(+), 48 deletions(-)
22
5 files changed, 64 insertions(+), 62 deletions(-)
22
23
23
v2: Minor changes in migration_ioc_process_incoming() to pass test cases
24
v6:
24
- https://lore.kernel.org/qemu-devel/20241129122256.96778-1-ppandit@redhat.com/
25
- Shutdown multifd threads before postcopy_start()
26
- Reorder tests/qtest/migration/ patches
27
- Some refactoring of functions
28
29
v5:
30
- https://lore.kernel.org/qemu-devel/20250205122712.229151-1-ppandit@redhat.com/T/#t
25
31
26
diff --git a/migration/migration.c b/migration/migration.c
32
diff --git a/migration/migration.c b/migration/migration.c
27
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
28
--- a/migration/migration.c
34
--- a/migration/migration.c
29
+++ b/migration/migration.c
35
+++ b/migration/migration.c
30
@@ -XXX,XX +XXX,XX @@ enum mig_rp_message_type {
36
@@ -XXX,XX +XXX,XX @@ enum mig_rp_message_type {
31
MIG_RP_MSG_MAX
37
MIG_RP_MSG_MAX
32
};
38
};
33
39
34
+/* Migration channel types */
40
+/* Migration channel types */
35
+enum { CH_DEFAULT, CH_MULTIFD, CH_POSTCOPY };
41
+enum { CH_MAIN, CH_MULTIFD, CH_POSTCOPY };
36
+
42
+
37
/* When we add fault tolerance, we could have several
43
/* When we add fault tolerance, we could have several
38
migrations at once. For now we don't need to add
44
migrations at once. For now we don't need to add
39
dynamic creation of migration */
45
dynamic creation of migration */
40
@@ -XXX,XX +XXX,XX @@ void migration_fd_process_incoming(QEMUFile *f)
46
@@ -XXX,XX +XXX,XX @@ void migration_fd_process_incoming(QEMUFile *f)
41
/*
47
migration_incoming_process();
42
* Returns true when we want to start a new incoming migration process,
48
}
43
* false otherwise.
49
44
+ *
50
-/*
45
+ * All the required channels must be in place before a new incoming
51
- * Returns true when we want to start a new incoming migration process,
46
+ * migration process starts.
52
- * false otherwise.
47
+ * - Multifd enabled:
53
- */
48
+ * The main channel and the multifd channels are required.
49
+ * - Multifd/Postcopy disabled:
50
+ * The main channel is required.
51
+ * - Postcopy enabled:
52
+ * We don't want to start a new incoming migration when
53
+ * the postcopy channel is created. Because it is created
54
+ * towards the end of the precopy migration.
55
+ *
56
*/
57
-static bool migration_should_start_incoming(bool main_channel)
54
-static bool migration_should_start_incoming(bool main_channel)
58
+static bool migration_should_start_incoming(uint8_t channel)
55
+static bool migration_has_main_and_multifd_channels(void)
59
{
56
{
60
- /* Multifd doesn't start unless all channels are established */
57
- /* Multifd doesn't start unless all channels are established */
61
- if (migrate_multifd()) {
58
- if (migrate_multifd()) {
62
- return migration_has_all_channels();
59
- return migration_has_all_channels();
63
- }
60
+ MigrationIncomingState *mis = migration_incoming_get_current();
64
+ bool ret = false;
61
+ if (!mis->from_src_file) {
65
+
62
+ /* main channel not established */
66
+ if (channel != CH_POSTCOPY) {
63
+ return false;
67
+ MigrationIncomingState *mis = migration_incoming_get_current();
64
}
68
+ ret = mis->from_src_file ? true : false;
69
65
70
- /* Preempt channel only starts when the main channel is created */
66
- /* Preempt channel only starts when the main channel is created */
71
- if (migrate_postcopy_preempt()) {
67
- if (migrate_postcopy_preempt()) {
72
- return main_channel;
68
- return main_channel;
73
+ if (ret && migrate_multifd()) {
69
+ if (migrate_multifd() && !multifd_recv_all_channels_created()) {
74
+ ret = multifd_recv_all_channels_created();
70
+ return false;
75
+ }
71
}
76
}
77
72
78
- /*
73
- /*
79
- * For all the rest types of migration, we should only reach here when
74
- * For all the rest types of migration, we should only reach here when
80
- * it's the main channel that's being created, and we should always
75
- * it's the main channel that's being created, and we should always
81
- * proceed with this channel.
76
- * proceed with this channel.
82
- */
77
- */
83
- assert(main_channel);
78
- assert(main_channel);
84
- return true;
79
+ /* main channel and all multifd channels are established */
85
+ return ret;
80
return true;
86
}
81
}
87
82
88
void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
89
@@ -XXX,XX +XXX,XX @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
83
@@ -XXX,XX +XXX,XX @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
90
MigrationIncomingState *mis = migration_incoming_get_current();
84
MigrationIncomingState *mis = migration_incoming_get_current();
91
Error *local_err = NULL;
85
Error *local_err = NULL;
92
QEMUFile *f;
86
QEMUFile *f;
93
- bool default_channel = true;
87
- bool default_channel = true;
94
uint32_t channel_magic = 0;
88
uint32_t channel_magic = 0;
95
+ uint8_t channel = CH_DEFAULT;
89
+ uint8_t channel = CH_MAIN;
96
int ret = 0;
90
int ret = 0;
97
91
98
- if (migrate_multifd() && !migrate_mapped_ram() &&
92
- if (migrate_multifd() && !migrate_mapped_ram() &&
99
- !migrate_postcopy_ram() &&
93
- !migrate_postcopy_ram() &&
100
- qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_READ_MSG_PEEK)) {
94
- qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_READ_MSG_PEEK)) {
101
+ if (!migration_should_start_incoming(channel)) {
95
+ if (!migration_has_main_and_multifd_channels()) {
102
+ if (qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_READ_MSG_PEEK)) {
96
+ if (qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_READ_MSG_PEEK)) {
103
/*
97
/*
104
* With multiple channels, it is possible that we receive channels
98
* With multiple channels, it is possible that we receive channels
105
* out of order on destination side, causing incorrect mapping of
99
* out of order on destination side, causing incorrect mapping of
106
@@ -XXX,XX +XXX,XX @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
100
@@ -XXX,XX +XXX,XX @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
...
...
116
+ }
110
+ }
117
111
118
- if (ret != 0) {
112
- if (ret != 0) {
119
- return;
113
- return;
120
+ if (channel_magic == cpu_to_be32(QEMU_VM_FILE_MAGIC)) {
114
+ if (channel_magic == cpu_to_be32(QEMU_VM_FILE_MAGIC)) {
121
+ channel = CH_DEFAULT;
115
+ channel = CH_MAIN;
122
+ } else if (channel_magic == cpu_to_be32(MULTIFD_MAGIC)) {
116
+ } else if (channel_magic == cpu_to_be32(MULTIFD_MAGIC)) {
123
+ channel = CH_MULTIFD;
117
+ channel = CH_MULTIFD;
124
+ } else if (!mis->from_src_file
118
+ } else if (!mis->from_src_file
125
+ && mis->state == MIGRATION_STATUS_POSTCOPY_PAUSED) {
119
+ && mis->state == MIGRATION_STATUS_POSTCOPY_PAUSED) {
126
+ /* reconnect default channel for postcopy recovery */
120
+ /* reconnect default channel for postcopy recovery */
127
+ channel = CH_DEFAULT;
121
+ channel = CH_MAIN;
128
+ } else {
122
+ } else {
129
+ error_report("%s: could not identify channel, unknown magic: %u",
123
+ error_report("%s: unknown channel magic: %u",
130
+ __func__, channel_magic);
124
+ __func__, channel_magic);
131
+ return;
125
+ return;
132
+ }
126
+ }
133
+ } else if (mis->from_src_file
127
+ } else if (mis->from_src_file
134
+ && (!strcmp(ioc->name, "migration-tls-incoming")
128
+ && (!strcmp(ioc->name, "migration-tls-incoming")
135
+ || !strcmp(ioc->name, "migration-file-incoming"))) {
129
+ || !strcmp(ioc->name, "migration-file-incoming"))) {
136
+ channel = CH_MULTIFD;
130
+ channel = CH_MULTIFD;
137
}
131
}
138
-
132
-
139
- default_channel = (channel_magic == cpu_to_be32(QEMU_VM_FILE_MAGIC));
133
- default_channel = (channel_magic == cpu_to_be32(QEMU_VM_FILE_MAGIC));
140
- } else {
134
- } else {
141
- default_channel = !mis->from_src_file;
135
- default_channel = !mis->from_src_file;
142
+ } else if (mis->from_src_file) { // && migrate_postcopy_preempt()
136
+ } else if (mis->from_src_file) {
143
+ channel = CH_POSTCOPY;
137
+ channel = CH_POSTCOPY;
144
}
138
}
145
139
146
if (multifd_recv_setup(errp) != 0) {
140
if (multifd_recv_setup(errp) != 0) {
147
return;
141
return;
148
}
142
}
149
143
150
- if (default_channel) {
144
- if (default_channel) {
151
+ if (channel == CH_DEFAULT) {
145
+ if (channel == CH_MAIN) {
152
f = qemu_file_new_input(ioc);
146
f = qemu_file_new_input(ioc);
153
migration_incoming_setup(f);
147
migration_incoming_setup(f);
154
- } else {
148
- } else {
155
+ } else if (channel == CH_MULTIFD) {
149
+ } else if (channel == CH_MULTIFD) {
156
/* Multiple connections */
150
/* Multiple connections */
...
...
172
+ f = qemu_file_new_input(ioc);
166
+ f = qemu_file_new_input(ioc);
173
+ postcopy_preempt_new_channel(mis, f);
167
+ postcopy_preempt_new_channel(mis, f);
174
}
168
}
175
169
176
- if (migration_should_start_incoming(default_channel)) {
170
- if (migration_should_start_incoming(default_channel)) {
177
+ if (migration_should_start_incoming(channel)) {
171
+ if (channel != CH_POSTCOPY && migration_has_main_and_multifd_channels()) {
178
/* If it's a recovery, we're done */
172
/* If it's a recovery, we're done */
179
if (postcopy_try_recover()) {
173
if (postcopy_try_recover()) {
180
return;
174
return;
181
@@ -XXX,XX +XXX,XX @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
175
@@ -XXX,XX +XXX,XX @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
182
*/
176
*/
183
bool migration_has_all_channels(void)
177
bool migration_has_all_channels(void)
184
{
178
{
185
+ bool ret = false;
179
+ if (!migration_has_main_and_multifd_channels()) {
180
+ return false;
181
+ }
182
+
186
MigrationIncomingState *mis = migration_incoming_get_current();
183
MigrationIncomingState *mis = migration_incoming_get_current();
187
184
-
188
if (!mis->from_src_file) {
185
- if (!mis->from_src_file) {
189
- return false;
186
+ if (migrate_postcopy_preempt() && !mis->postcopy_qemufile_dst) {
190
+ return ret;
187
return false;
191
}
188
}
192
189
193
if (migrate_multifd()) {
190
- if (migrate_multifd()) {
194
- return multifd_recv_all_channels_created();
191
- return multifd_recv_all_channels_created();
195
+ ret = multifd_recv_all_channels_created();
192
- }
196
}
193
-
197
198
- if (migrate_postcopy_preempt()) {
194
- if (migrate_postcopy_preempt()) {
199
- return mis->postcopy_qemufile_dst != NULL;
195
- return mis->postcopy_qemufile_dst != NULL;
200
+ if (ret && migrate_postcopy_preempt()) {
196
- }
201
+ ret = mis->postcopy_qemufile_dst != NULL;
197
-
202
}
198
return true;
203
204
- return true;
205
+ return ret;
206
}
199
}
207
200
208
int migrate_send_rp_switchover_ack(MigrationIncomingState *mis)
201
@@ -XXX,XX +XXX,XX @@ static void migrate_fd_cleanup(MigrationState *s)
202
203
assert(!migration_is_active());
204
205
+ file_cleanup_outgoing_migration();
206
+ socket_cleanup_outgoing_migration();
207
if (s->state == MIGRATION_STATUS_CANCELLING) {
208
migrate_set_state(&s->state, MIGRATION_STATUS_CANCELLING,
209
MIGRATION_STATUS_CANCELLED);
210
@@ -XXX,XX +XXX,XX @@ static MigIterateState migration_iteration_run(MigrationState *s)
211
}
212
213
/* Still a significant amount to transfer */
214
- if (!in_postcopy && must_precopy <= s->threshold_size && can_switchover &&
215
- qatomic_read(&s->start_postcopy)) {
216
+ if (!in_postcopy && must_precopy <= s->threshold_size
217
+ && can_switchover && qatomic_read(&s->start_postcopy)) {
218
+ if (migrate_multifd()) {
219
+ multifd_send_shutdown();
220
+ }
221
if (postcopy_start(s, &local_err)) {
222
migrate_set_error(s, local_err);
223
error_report_err(local_err);
209
diff --git a/migration/multifd-nocomp.c b/migration/multifd-nocomp.c
224
diff --git a/migration/multifd-nocomp.c b/migration/multifd-nocomp.c
210
index XXXXXXX..XXXXXXX 100644
225
index XXXXXXX..XXXXXXX 100644
211
--- a/migration/multifd-nocomp.c
226
--- a/migration/multifd-nocomp.c
212
+++ b/migration/multifd-nocomp.c
227
+++ b/migration/multifd-nocomp.c
213
@@ -XXX,XX +XXX,XX @@
228
@@ -XXX,XX +XXX,XX @@
...
...
224
239
225
- if (!migrate_multifd()) {
240
- if (!migrate_multifd()) {
226
+ if (!migrate_multifd() || migration_in_postcopy()) {
241
+ if (!migrate_multifd() || migration_in_postcopy()) {
227
return 0;
242
return 0;
228
}
243
}
244
245
diff --git a/migration/multifd.c b/migration/multifd.c
246
index XXXXXXX..XXXXXXX 100644
247
--- a/migration/multifd.c
248
+++ b/migration/multifd.c
249
@@ -XXX,XX +XXX,XX @@ static bool multifd_send_cleanup_channel(MultiFDSendParams *p, Error **errp)
250
251
static void multifd_send_cleanup_state(void)
252
{
253
- file_cleanup_outgoing_migration();
254
- socket_cleanup_outgoing_migration();
255
qemu_sem_destroy(&multifd_send_state->channels_created);
256
qemu_sem_destroy(&multifd_send_state->channels_ready);
257
g_free(multifd_send_state->params);
258
@@ -XXX,XX +XXX,XX @@ void multifd_send_shutdown(void)
259
{
260
int i;
261
262
- if (!migrate_multifd()) {
263
+ if (!migrate_multifd() || !multifd_send_state) {
264
return;
265
}
229
266
230
diff --git a/migration/options.c b/migration/options.c
267
diff --git a/migration/options.c b/migration/options.c
231
index XXXXXXX..XXXXXXX 100644
268
index XXXXXXX..XXXXXXX 100644
232
--- a/migration/options.c
269
--- a/migration/options.c
233
+++ b/migration/options.c
270
+++ b/migration/options.c
...
...
259
@@ -XXX,XX +XXX,XX @@ static int ram_save_target_page(RAMState *rs, PageSearchStatus *pss)
296
@@ -XXX,XX +XXX,XX @@ static int ram_save_target_page(RAMState *rs, PageSearchStatus *pss)
260
}
297
}
261
}
298
}
262
299
263
- if (migrate_multifd()) {
300
- if (migrate_multifd()) {
301
- RAMBlock *block = pss->block;
302
- return ram_save_multifd_page(block, offset);
264
+ if (migrate_multifd() && !migration_in_postcopy()) {
303
+ if (migrate_multifd() && !migration_in_postcopy()) {
265
RAMBlock *block = pss->block;
304
+ return ram_save_multifd_page(pss->block, offset);
266
return ram_save_multifd_page(block, offset);
305
}
267
}
306
268
--
307
if (control_save_page(pss, offset, &res)) {
308
--
269
2.48.1
309
2.48.1
diff view generated by jsdifflib
1
From: Prasad Pandit <pjp@fedoraproject.org>
1
From: Prasad Pandit <pjp@fedoraproject.org>
2
2
3
Refactor ram_save_target_page legacy and multifd
3
Migration capabilities are set in multiple '.start_hook'
4
functions into one. Other than simplifying it,
4
functions for various tests. Instead, consolidate setting
5
it frees 'migration_ops' object from usage, so it
5
capabilities in 'set_migration_capabilities()' function
6
is expunged.
6
which is called from various 'test_*_common()' functions.
7
While simplifying the capabilities setting, it helps
8
to declutter the qtest sources.
7
9
10
Suggested-by: Fabiano Rosas <farosas@suse.de>
8
Signed-off-by: Prasad Pandit <pjp@fedoraproject.org>
11
Signed-off-by: Prasad Pandit <pjp@fedoraproject.org>
9
---
12
---
10
migration/ram.c | 67 +++++++++++++------------------------------------
13
tests/qtest/migration/compression-tests.c | 10 ++--
11
1 file changed, 17 insertions(+), 50 deletions(-)
14
tests/qtest/migration/cpr-tests.c | 4 +-
15
tests/qtest/migration/file-tests.c | 44 +++++-------------
16
tests/qtest/migration/framework.c | 56 +++++++++++++++++------
17
tests/qtest/migration/framework.h | 4 +-
18
tests/qtest/migration/postcopy-tests.c | 4 +-
19
tests/qtest/migration/precopy-tests.c | 19 +++-----
20
tests/qtest/migration/tls-tests.c | 11 ++++-
21
8 files changed, 80 insertions(+), 72 deletions(-)
12
22
13
v2:
23
v6:
14
- https://lore.kernel.org/qemu-devel/20241129122256.96778-1-ppandit@redhat.com/
24
- Reorder, make this the first qtest patch in this series.
15
25
16
diff --git a/migration/ram.c b/migration/ram.c
26
v5:
17
index XXXXXXX..XXXXXXX 100644
27
- https://lore.kernel.org/qemu-devel/20250205122712.229151-1-ppandit@redhat.com/T/#t
18
--- a/migration/ram.c
28
19
+++ b/migration/ram.c
29
diff --git a/tests/qtest/migration/compression-tests.c b/tests/qtest/migration/compression-tests.c
20
@@ -XXX,XX +XXX,XX @@ void ram_transferred_add(uint64_t bytes)
30
index XXXXXXX..XXXXXXX 100644
21
}
31
--- a/tests/qtest/migration/compression-tests.c
22
}
32
+++ b/tests/qtest/migration/compression-tests.c
23
33
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_zstd(void)
24
-struct MigrationOps {
34
{
25
- int (*ram_save_target_page)(RAMState *rs, PageSearchStatus *pss);
35
MigrateCommon args = {
26
-};
36
.listen_uri = "defer",
27
-typedef struct MigrationOps MigrationOps;
37
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
28
-
38
.start_hook = migrate_hook_start_precopy_tcp_multifd_zstd,
29
-MigrationOps *migration_ops;
39
};
30
-
40
test_precopy_common(&args);
31
static int ram_save_host_page_urgent(PageSearchStatus *pss);
41
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_qatzip(void)
32
42
{
33
/* NOTE: page is the PFN not real ram_addr_t. */
43
MigrateCommon args = {
34
@@ -XXX,XX +XXX,XX @@ int ram_save_queue_pages(const char *rbname, ram_addr_t start, ram_addr_t len,
44
.listen_uri = "defer",
35
}
45
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
36
46
.start_hook = migrate_hook_start_precopy_tcp_multifd_qatzip,
37
/**
47
};
38
- * ram_save_target_page_legacy: save one target page
48
test_precopy_common(&args);
39
- *
49
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_qpl(void)
40
- * Returns the number of pages written
50
{
41
+ * ram_save_target_page: save one target page to the precopy thread
51
MigrateCommon args = {
42
+ * OR to multifd workers.
52
.listen_uri = "defer",
43
*
53
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
44
* @rs: current RAM state
54
.start_hook = migrate_hook_start_precopy_tcp_multifd_qpl,
45
* @pss: data about the page we want to send
55
};
46
*/
56
test_precopy_common(&args);
47
-static int ram_save_target_page_legacy(RAMState *rs, PageSearchStatus *pss)
57
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_uadk(void)
48
+static int ram_save_target_page(RAMState *rs, PageSearchStatus *pss)
58
{
49
{
59
MigrateCommon args = {
50
ram_addr_t offset = ((ram_addr_t)pss->page) << TARGET_PAGE_BITS;
60
.listen_uri = "defer",
51
int res;
61
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
52
62
.start_hook = migrate_hook_start_precopy_tcp_multifd_uadk,
53
+ if (!migrate_multifd()
63
};
54
+ || migrate_zero_page_detection() == ZERO_PAGE_DETECTION_LEGACY) {
64
test_precopy_common(&args);
55
+ if (save_zero_page(rs, pss, offset)) {
65
@@ -XXX,XX +XXX,XX @@ migrate_hook_start_xbzrle(QTestState *from,
56
+ return 1;
66
QTestState *to)
67
{
68
migrate_set_parameter_int(from, "xbzrle-cache-size", 33554432);
69
-
70
- migrate_set_capability(from, "xbzrle", true);
71
- migrate_set_capability(to, "xbzrle", true);
72
-
73
return NULL;
74
}
75
76
@@ -XXX,XX +XXX,XX @@ static void test_precopy_unix_xbzrle(void)
77
.listen_uri = uri,
78
.start_hook = migrate_hook_start_xbzrle,
79
.iterations = 2,
80
+ .caps[MIGRATION_CAPABILITY_XBZRLE] = true,
81
/*
82
* XBZRLE needs pages to be modified when doing the 2nd+ round
83
* iteration to have real data pushed to the stream.
84
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_zlib(void)
85
{
86
MigrateCommon args = {
87
.listen_uri = "defer",
88
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
89
.start_hook = migrate_hook_start_precopy_tcp_multifd_zlib,
90
};
91
test_precopy_common(&args);
92
diff --git a/tests/qtest/migration/cpr-tests.c b/tests/qtest/migration/cpr-tests.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/tests/qtest/migration/cpr-tests.c
95
+++ b/tests/qtest/migration/cpr-tests.c
96
@@ -XXX,XX +XXX,XX @@ static void *migrate_hook_start_mode_reboot(QTestState *from, QTestState *to)
97
migrate_set_parameter_str(from, "mode", "cpr-reboot");
98
migrate_set_parameter_str(to, "mode", "cpr-reboot");
99
100
- migrate_set_capability(from, "x-ignore-shared", true);
101
- migrate_set_capability(to, "x-ignore-shared", true);
102
-
103
return NULL;
104
}
105
106
@@ -XXX,XX +XXX,XX @@ static void test_mode_reboot(void)
107
.connect_uri = uri,
108
.listen_uri = "defer",
109
.start_hook = migrate_hook_start_mode_reboot,
110
+ .caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED] = true,
111
};
112
113
test_file_common(&args, true);
114
diff --git a/tests/qtest/migration/file-tests.c b/tests/qtest/migration/file-tests.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/tests/qtest/migration/file-tests.c
117
+++ b/tests/qtest/migration/file-tests.c
118
@@ -XXX,XX +XXX,XX @@ static void test_precopy_file_offset_bad(void)
119
test_file_common(&args, false);
120
}
121
122
-static void *migrate_hook_start_mapped_ram(QTestState *from,
123
- QTestState *to)
124
-{
125
- migrate_set_capability(from, "mapped-ram", true);
126
- migrate_set_capability(to, "mapped-ram", true);
127
-
128
- return NULL;
129
-}
130
-
131
static void test_precopy_file_mapped_ram_live(void)
132
{
133
g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
134
@@ -XXX,XX +XXX,XX @@ static void test_precopy_file_mapped_ram_live(void)
135
MigrateCommon args = {
136
.connect_uri = uri,
137
.listen_uri = "defer",
138
- .start_hook = migrate_hook_start_mapped_ram,
139
+ .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true,
140
};
141
142
test_file_common(&args, false);
143
@@ -XXX,XX +XXX,XX @@ static void test_precopy_file_mapped_ram(void)
144
MigrateCommon args = {
145
.connect_uri = uri,
146
.listen_uri = "defer",
147
- .start_hook = migrate_hook_start_mapped_ram,
148
+ .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true,
149
};
150
151
test_file_common(&args, true);
152
}
153
154
-static void *migrate_hook_start_multifd_mapped_ram(QTestState *from,
155
- QTestState *to)
156
-{
157
- migrate_hook_start_mapped_ram(from, to);
158
-
159
- migrate_set_parameter_int(from, "multifd-channels", 4);
160
- migrate_set_parameter_int(to, "multifd-channels", 4);
161
-
162
- migrate_set_capability(from, "multifd", true);
163
- migrate_set_capability(to, "multifd", true);
164
-
165
- return NULL;
166
-}
167
-
168
static void test_multifd_file_mapped_ram_live(void)
169
{
170
g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
171
@@ -XXX,XX +XXX,XX @@ static void test_multifd_file_mapped_ram_live(void)
172
MigrateCommon args = {
173
.connect_uri = uri,
174
.listen_uri = "defer",
175
- .start_hook = migrate_hook_start_multifd_mapped_ram,
176
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
177
+ .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true,
178
};
179
180
test_file_common(&args, false);
181
@@ -XXX,XX +XXX,XX @@ static void test_multifd_file_mapped_ram(void)
182
MigrateCommon args = {
183
.connect_uri = uri,
184
.listen_uri = "defer",
185
- .start_hook = migrate_hook_start_multifd_mapped_ram,
186
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
187
+ .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true,
188
};
189
190
test_file_common(&args, true);
191
@@ -XXX,XX +XXX,XX @@ static void test_multifd_file_mapped_ram(void)
192
static void *migrate_hook_start_multifd_mapped_ram_dio(QTestState *from,
193
QTestState *to)
194
{
195
- migrate_hook_start_multifd_mapped_ram(from, to);
196
-
197
migrate_set_parameter_bool(from, "direct-io", true);
198
migrate_set_parameter_bool(to, "direct-io", true);
199
200
@@ -XXX,XX +XXX,XX @@ static void test_multifd_file_mapped_ram_dio(void)
201
.connect_uri = uri,
202
.listen_uri = "defer",
203
.start_hook = migrate_hook_start_multifd_mapped_ram_dio,
204
+ .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true,
205
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
206
};
207
208
if (!probe_o_direct_support(tmpfs)) {
209
@@ -XXX,XX +XXX,XX @@ static void *migrate_hook_start_multifd_mapped_ram_fdset_dio(QTestState *from,
210
fdset_add_fds(from, file, O_WRONLY, 2, true);
211
fdset_add_fds(to, file, O_RDONLY, 2, true);
212
213
- migrate_hook_start_multifd_mapped_ram(from, to);
214
migrate_set_parameter_bool(from, "direct-io", true);
215
migrate_set_parameter_bool(to, "direct-io", true);
216
217
@@ -XXX,XX +XXX,XX @@ static void *migrate_hook_start_multifd_mapped_ram_fdset(QTestState *from,
218
fdset_add_fds(from, file, O_WRONLY, 2, false);
219
fdset_add_fds(to, file, O_RDONLY, 2, false);
220
221
- migrate_hook_start_multifd_mapped_ram(from, to);
222
-
223
return NULL;
224
}
225
226
@@ -XXX,XX +XXX,XX @@ static void test_multifd_file_mapped_ram_fdset(void)
227
.listen_uri = "defer",
228
.start_hook = migrate_hook_start_multifd_mapped_ram_fdset,
229
.end_hook = migrate_hook_end_multifd_mapped_ram_fdset,
230
+ .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true,
231
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
232
};
233
234
test_file_common(&args, true);
235
@@ -XXX,XX +XXX,XX @@ static void test_multifd_file_mapped_ram_fdset_dio(void)
236
.listen_uri = "defer",
237
.start_hook = migrate_hook_start_multifd_mapped_ram_fdset_dio,
238
.end_hook = migrate_hook_end_multifd_mapped_ram_fdset,
239
+ .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true,
240
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
241
};
242
243
if (!probe_o_direct_support(tmpfs)) {
244
diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c
245
index XXXXXXX..XXXXXXX 100644
246
--- a/tests/qtest/migration/framework.c
247
+++ b/tests/qtest/migration/framework.c
248
@@ -XXX,XX +XXX,XX @@ static QList *migrate_start_get_qmp_capabilities(const MigrateStart *args)
249
return capabilities;
250
}
251
252
+static void set_migration_capabilities(QTestState *from,
253
+ QTestState *to, MigrateCommon *args)
254
+{
255
+ /*
256
+ * MigrationCapability_lookup and MIGRATION_CAPABILITY_ constants
257
+ * are from qapi-types-migration.h.
258
+ */
259
+ for (uint8_t i = 0; i < MIGRATION_CAPABILITY__MAX; i++)
260
+ {
261
+ if (!args->caps[i]) {
262
+ continue;
263
+ }
264
+ if (from) {
265
+ migrate_set_capability(from,
266
+ MigrationCapability_lookup.array[i], true);
267
+ }
268
+ if (to) {
269
+ migrate_set_capability(to,
270
+ MigrationCapability_lookup.array[i], true);
57
+ }
271
+ }
58
+ }
272
+ }
59
+
273
+
60
+ if (migrate_multifd()) {
274
+ return;
61
+ RAMBlock *block = pss->block;
275
+}
62
+ return ram_save_multifd_page(block, offset);
276
+
277
int migrate_start(QTestState **from, QTestState **to, const char *uri,
278
MigrateStart *args)
279
{
280
@@ -XXX,XX +XXX,XX @@ static int migrate_postcopy_prepare(QTestState **from_ptr,
281
args->postcopy_data = args->start_hook(from, to);
282
}
283
284
- migrate_set_capability(from, "postcopy-ram", true);
285
- migrate_set_capability(to, "postcopy-ram", true);
286
- migrate_set_capability(to, "postcopy-blocktime", true);
287
-
288
- if (args->postcopy_preempt) {
289
- migrate_set_capability(from, "postcopy-preempt", true);
290
- migrate_set_capability(to, "postcopy-preempt", true);
291
- }
292
+ /* set postcopy capabilities */
293
+ args->caps[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME] = true;
294
+ args->caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] = true;
295
+ set_migration_capabilities(from, to, args);
296
297
migrate_ensure_non_converge(from);
298
-
299
migrate_prepare_for_dirty_mem(from);
300
qtest_qmp_assert_success(to, "{ 'execute': 'migrate-incoming',"
301
" 'arguments': { "
302
@@ -XXX,XX +XXX,XX @@ void test_precopy_common(MigrateCommon *args)
303
return;
304
}
305
306
+ set_migration_capabilities(from, to, args);
307
+ if (args->caps[MIGRATION_CAPABILITY_MULTIFD]) {
308
+ migrate_set_parameter_int(from, "multifd-channels", 16);
309
+ migrate_set_parameter_int(to, "multifd-channels", 16);
63
+ }
310
+ }
64
+
311
+
65
if (control_save_page(pss, offset, &res)) {
312
if (args->start_hook) {
66
return res;
313
data_hook = args->start_hook(from, to);
67
}
314
}
68
315
@@ -XXX,XX +XXX,XX @@ void test_file_common(MigrateCommon *args, bool stop_src)
69
- if (save_zero_page(rs, pss, offset)) {
316
*/
70
- return 1;
317
g_assert_false(args->live);
71
- }
318
72
-
319
+ set_migration_capabilities(from, to, args);
73
return ram_save_page(rs, pss);
320
+ if (args->caps[MIGRATION_CAPABILITY_MULTIFD]) {
74
}
321
+ migrate_set_parameter_int(from, "multifd-channels", 4);
75
322
+ migrate_set_parameter_int(to, "multifd-channels", 4);
76
-/**
323
+ }
77
- * ram_save_target_page_multifd: send one target page to multifd workers
324
+
78
- *
325
if (g_strrstr(args->connect_uri, "offset=")) {
79
- * Returns 1 if the page was queued, -1 otherwise.
326
check_offset = true;
80
- *
327
/*
81
- * @rs: current RAM state
328
@@ -XXX,XX +XXX,XX @@ void *migrate_hook_start_precopy_tcp_multifd_common(QTestState *from,
82
- * @pss: data about the page we want to send
329
QTestState *to,
83
- */
330
const char *method)
84
-static int ram_save_target_page_multifd(RAMState *rs, PageSearchStatus *pss)
331
{
332
- migrate_set_parameter_int(from, "multifd-channels", 16);
333
- migrate_set_parameter_int(to, "multifd-channels", 16);
334
-
335
migrate_set_parameter_str(from, "multifd-compression", method);
336
migrate_set_parameter_str(to, "multifd-compression", method);
337
338
- migrate_set_capability(from, "multifd", true);
339
- migrate_set_capability(to, "multifd", true);
340
-
341
/* Start incoming migration from the 1st socket */
342
migrate_incoming_qmp(to, "tcp:127.0.0.1:0", NULL, "{}");
343
344
diff --git a/tests/qtest/migration/framework.h b/tests/qtest/migration/framework.h
345
index XXXXXXX..XXXXXXX 100644
346
--- a/tests/qtest/migration/framework.h
347
+++ b/tests/qtest/migration/framework.h
348
@@ -XXX,XX +XXX,XX @@
349
#define TEST_FRAMEWORK_H
350
351
#include "libqtest.h"
352
+#include <qapi/qapi-types-migration.h>
353
354
#define FILE_TEST_FILENAME "migfile"
355
#define FILE_TEST_OFFSET 0x1000
356
@@ -XXX,XX +XXX,XX @@ typedef struct {
357
358
/* Postcopy specific fields */
359
void *postcopy_data;
360
- bool postcopy_preempt;
361
PostcopyRecoveryFailStage postcopy_recovery_fail_stage;
362
+
363
+ bool caps[MIGRATION_CAPABILITY__MAX];
364
} MigrateCommon;
365
366
void wait_for_serial(const char *side);
367
diff --git a/tests/qtest/migration/postcopy-tests.c b/tests/qtest/migration/postcopy-tests.c
368
index XXXXXXX..XXXXXXX 100644
369
--- a/tests/qtest/migration/postcopy-tests.c
370
+++ b/tests/qtest/migration/postcopy-tests.c
371
@@ -XXX,XX +XXX,XX @@ static void test_postcopy_suspend(void)
372
static void test_postcopy_preempt(void)
373
{
374
MigrateCommon args = {
375
- .postcopy_preempt = true,
376
+ .caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT] = true,
377
};
378
379
test_postcopy_common(&args);
380
@@ -XXX,XX +XXX,XX @@ static void test_postcopy_recovery_fail_reconnect(void)
381
static void test_postcopy_preempt_recovery(void)
382
{
383
MigrateCommon args = {
384
- .postcopy_preempt = true,
385
+ .caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT] = true,
386
};
387
388
test_postcopy_recovery_common(&args);
389
diff --git a/tests/qtest/migration/precopy-tests.c b/tests/qtest/migration/precopy-tests.c
390
index XXXXXXX..XXXXXXX 100644
391
--- a/tests/qtest/migration/precopy-tests.c
392
+++ b/tests/qtest/migration/precopy-tests.c
393
@@ -XXX,XX +XXX,XX @@ static void test_precopy_tcp_plain(void)
394
test_precopy_common(&args);
395
}
396
397
-static void *migrate_hook_start_switchover_ack(QTestState *from, QTestState *to)
85
-{
398
-{
86
- RAMBlock *block = pss->block;
399
-
87
- ram_addr_t offset = ((ram_addr_t)pss->page) << TARGET_PAGE_BITS;
400
- migrate_set_capability(from, "return-path", true);
88
-
401
- migrate_set_capability(to, "return-path", true);
89
- /*
402
-
90
- * While using multifd live migration, we still need to handle zero
403
- migrate_set_capability(from, "switchover-ack", true);
91
- * page checking on the migration main thread.
404
- migrate_set_capability(to, "switchover-ack", true);
92
- */
405
-
93
- if (migrate_zero_page_detection() == ZERO_PAGE_DETECTION_LEGACY) {
406
- return NULL;
94
- if (save_zero_page(rs, pss, offset)) {
95
- return 1;
96
- }
97
- }
98
-
99
- return ram_save_multifd_page(block, offset);
100
-}
407
-}
101
-
408
-
102
/* Should be called before sending a host page */
409
static void test_precopy_tcp_switchover_ack(void)
103
static void pss_host_page_prepare(PageSearchStatus *pss)
410
{
104
{
411
MigrateCommon args = {
105
@@ -XXX,XX +XXX,XX @@ static int ram_save_host_page_urgent(PageSearchStatus *pss)
412
.listen_uri = "tcp:127.0.0.1:0",
106
413
- .start_hook = migrate_hook_start_switchover_ack,
107
if (page_dirty) {
414
+ .caps[MIGRATION_CAPABILITY_RETURN_PATH] = true,
108
/* Be strict to return code; it must be 1, or what else? */
415
+ .caps[MIGRATION_CAPABILITY_SWITCHOVER_ACK] = true,
109
- if (migration_ops->ram_save_target_page(rs, pss) != 1) {
416
/*
110
+ if (ram_save_target_page(rs, pss) != 1) {
417
* Source VM must be running in order to consider the switchover ACK
111
error_report_once("%s: ram_save_target_page failed", __func__);
418
* when deciding to do switchover or not.
112
ret = -1;
419
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_uri_none(void)
113
goto out;
420
MigrateCommon args = {
114
@@ -XXX,XX +XXX,XX @@ static int ram_save_host_page(RAMState *rs, PageSearchStatus *pss)
421
.listen_uri = "defer",
115
if (preempt_active) {
422
.start_hook = migrate_hook_start_precopy_tcp_multifd,
116
qemu_mutex_unlock(&rs->bitmap_mutex);
423
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
117
}
424
/*
118
- tmppages = migration_ops->ram_save_target_page(rs, pss);
425
* Multifd is more complicated than most of the features, it
119
+ tmppages = ram_save_target_page(rs, pss);
426
* directly takes guest page buffers when sending, make sure
120
if (tmppages >= 0) {
427
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_zero_page_legacy(void)
121
pages += tmppages;
428
MigrateCommon args = {
122
/*
429
.listen_uri = "defer",
123
@@ -XXX,XX +XXX,XX @@ static void ram_save_cleanup(void *opaque)
430
.start_hook = migrate_hook_start_precopy_tcp_multifd_zero_page_legacy,
124
xbzrle_cleanup();
431
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
125
multifd_ram_save_cleanup();
432
/*
126
ram_state_cleanup(rsp);
433
* Multifd is more complicated than most of the features, it
127
- g_free(migration_ops);
434
* directly takes guest page buffers when sending, make sure
128
- migration_ops = NULL;
435
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_no_zero_page(void)
129
}
436
MigrateCommon args = {
130
437
.listen_uri = "defer",
131
static void ram_state_reset(RAMState *rs)
438
.start_hook = migrate_hook_start_precopy_tcp_multifd_no_zero_page,
132
@@ -XXX,XX +XXX,XX @@ static int ram_save_setup(QEMUFile *f, void *opaque, Error **errp)
439
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
133
return ret;
440
/*
134
}
441
* Multifd is more complicated than most of the features, it
135
442
* directly takes guest page buffers when sending, make sure
136
- migration_ops = g_malloc0(sizeof(MigrationOps));
443
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_channels_none(void)
137
-
444
.listen_uri = "defer",
138
if (migrate_multifd()) {
445
.start_hook = migrate_hook_start_precopy_tcp_multifd,
139
multifd_ram_save_setup();
446
.live = true,
140
- migration_ops->ram_save_target_page = ram_save_target_page_multifd;
447
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
141
- } else {
448
.connect_channels = ("[ { 'channel-type': 'main',"
142
- migration_ops->ram_save_target_page = ram_save_target_page_legacy;
449
" 'addr': { 'transport': 'socket',"
143
}
450
" 'type': 'inet',"
144
451
diff --git a/tests/qtest/migration/tls-tests.c b/tests/qtest/migration/tls-tests.c
145
/*
452
index XXXXXXX..XXXXXXX 100644
146
--
453
--- a/tests/qtest/migration/tls-tests.c
454
+++ b/tests/qtest/migration/tls-tests.c
455
@@ -XXX,XX +XXX,XX @@ static void test_postcopy_tls_psk(void)
456
static void test_postcopy_preempt_tls_psk(void)
457
{
458
MigrateCommon args = {
459
- .postcopy_preempt = true,
460
.start_hook = migrate_hook_start_tls_psk_match,
461
.end_hook = migrate_hook_end_tls_psk,
462
+ .caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT] = true,
463
};
464
465
test_postcopy_common(&args);
466
@@ -XXX,XX +XXX,XX @@ static void test_postcopy_recovery_tls_psk(void)
467
static void test_postcopy_preempt_all(void)
468
{
469
MigrateCommon args = {
470
- .postcopy_preempt = true,
471
.start_hook = migrate_hook_start_tls_psk_match,
472
.end_hook = migrate_hook_end_tls_psk,
473
+ .caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT] = true,
474
};
475
476
test_postcopy_recovery_common(&args);
477
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_tls_psk_match(void)
478
.listen_uri = "defer",
479
.start_hook = migrate_hook_start_multifd_tcp_tls_psk_match,
480
.end_hook = migrate_hook_end_tls_psk,
481
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
482
};
483
test_precopy_common(&args);
484
}
485
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_tls_psk_mismatch(void)
486
.start_hook = migrate_hook_start_multifd_tcp_tls_psk_mismatch,
487
.end_hook = migrate_hook_end_tls_psk,
488
.result = MIG_TEST_FAIL,
489
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
490
};
491
test_precopy_common(&args);
492
}
493
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_tls_x509_default_host(void)
494
.listen_uri = "defer",
495
.start_hook = migrate_hook_start_multifd_tls_x509_default_host,
496
.end_hook = migrate_hook_end_tls_x509,
497
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
498
};
499
test_precopy_common(&args);
500
}
501
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_tls_x509_override_host(void)
502
.listen_uri = "defer",
503
.start_hook = migrate_hook_start_multifd_tls_x509_override_host,
504
.end_hook = migrate_hook_end_tls_x509,
505
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
506
};
507
test_precopy_common(&args);
508
}
509
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_tls_x509_mismatch_host(void)
510
.start_hook = migrate_hook_start_multifd_tls_x509_mismatch_host,
511
.end_hook = migrate_hook_end_tls_x509,
512
.result = MIG_TEST_FAIL,
513
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
514
};
515
test_precopy_common(&args);
516
}
517
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_tls_x509_allow_anon_client(void)
518
.listen_uri = "defer",
519
.start_hook = migrate_hook_start_multifd_tls_x509_allow_anon_client,
520
.end_hook = migrate_hook_end_tls_x509,
521
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
522
};
523
test_precopy_common(&args);
524
}
525
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_tls_x509_reject_anon_client(void)
526
.start_hook = migrate_hook_start_multifd_tls_x509_reject_anon_client,
527
.end_hook = migrate_hook_end_tls_x509,
528
.result = MIG_TEST_FAIL,
529
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
530
};
531
test_precopy_common(&args);
532
}
533
--
147
2.48.1
534
2.48.1
diff view generated by jsdifflib
1
From: Prasad Pandit <pjp@fedoraproject.org>
1
From: Prasad Pandit <pjp@fedoraproject.org>
2
2
3
Add a new postcopy test 'migration/postcopy/multifd'
3
Add new qtests to run postcopy migration with multifd
4
to run postcopy migration with multifd channels enabled.
4
channels enabled.
5
Add a boolean field 'multifd' to the MigrateCommon struct.
6
It helps to enable multifd channels.
7
5
8
Signed-off-by: Prasad Pandit <pjp@fedoraproject.org>
6
Signed-off-by: Prasad Pandit <pjp@fedoraproject.org>
9
---
7
---
10
tests/qtest/migration/framework.c | 8 ++++++++
8
tests/qtest/migration/compression-tests.c | 13 ++++++++
11
tests/qtest/migration/framework.h | 3 +++
9
tests/qtest/migration/framework.c | 4 +++
12
tests/qtest/migration/postcopy-tests.c | 10 ++++++++++
10
tests/qtest/migration/postcopy-tests.c | 23 +++++++++++++
13
3 files changed, 21 insertions(+)
11
tests/qtest/migration/precopy-tests.c | 19 +++++++++++
14
12
tests/qtest/migration/tls-tests.c | 40 +++++++++++++++++++++++
13
5 files changed, 99 insertions(+)
14
15
v6:
16
- Reorder, make this the second patch in this series.
17
18
v5:
19
- https://lore.kernel.org/qemu-devel/20250205122712.229151-1-ppandit@redhat.com/T/#t
20
21
diff --git a/tests/qtest/migration/compression-tests.c b/tests/qtest/migration/compression-tests.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/tests/qtest/migration/compression-tests.c
24
+++ b/tests/qtest/migration/compression-tests.c
25
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_zstd(void)
26
};
27
test_precopy_common(&args);
28
}
29
+
30
+static void test_multifd_postcopy_tcp_zstd(void)
31
+{
32
+ MigrateCommon args = {
33
+ .listen_uri = "defer",
34
+ .caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] = true,
35
+ .start_hook = migrate_hook_start_precopy_tcp_multifd_zstd,
36
+ };
37
+
38
+ test_precopy_common(&args);
39
+}
40
#endif /* CONFIG_ZSTD */
41
42
#ifdef CONFIG_QATZIP
43
@@ -XXX,XX +XXX,XX @@ void migration_test_add_compression(MigrationTestEnv *env)
44
#ifdef CONFIG_ZSTD
45
migration_test_add("/migration/multifd/tcp/plain/zstd",
46
test_multifd_tcp_zstd);
47
+ migration_test_add("/migration/multifd+postcopy/tcp/plain/zstd",
48
+ test_multifd_postcopy_tcp_zstd);
49
#endif
50
51
#ifdef CONFIG_QATZIP
15
diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c
52
diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c
16
index XXXXXXX..XXXXXXX 100644
53
index XXXXXXX..XXXXXXX 100644
17
--- a/tests/qtest/migration/framework.c
54
--- a/tests/qtest/migration/framework.c
18
+++ b/tests/qtest/migration/framework.c
55
+++ b/tests/qtest/migration/framework.c
19
@@ -XXX,XX +XXX,XX @@ static int migrate_postcopy_prepare(QTestState **from_ptr,
56
@@ -XXX,XX +XXX,XX @@ static int migrate_postcopy_prepare(QTestState **from_ptr,
20
migrate_set_capability(to, "postcopy-preempt", true);
57
args->caps[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME] = true;
21
}
58
args->caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] = true;
22
59
set_migration_capabilities(from, to, args);
23
+ if (args->multifd) {
60
+ if (args->caps[MIGRATION_CAPABILITY_MULTIFD]) {
24
+ migrate_set_capability(from, "multifd", true);
25
+ migrate_set_capability(to, "multifd", true);
26
+
27
+ migrate_set_parameter_int(from, "multifd-channels", 8);
61
+ migrate_set_parameter_int(from, "multifd-channels", 8);
28
+ migrate_set_parameter_int(to, "multifd-channels", 8);
62
+ migrate_set_parameter_int(to, "multifd-channels", 8);
29
+ }
63
+ }
30
+
64
31
migrate_ensure_non_converge(from);
65
migrate_ensure_non_converge(from);
32
33
migrate_prepare_for_dirty_mem(from);
66
migrate_prepare_for_dirty_mem(from);
34
diff --git a/tests/qtest/migration/framework.h b/tests/qtest/migration/framework.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/tests/qtest/migration/framework.h
37
+++ b/tests/qtest/migration/framework.h
38
@@ -XXX,XX +XXX,XX @@ typedef struct {
39
*/
40
bool live;
41
42
+ /* set multifd on */
43
+ bool multifd;
44
+
45
/* Postcopy specific fields */
46
void *postcopy_data;
47
bool postcopy_preempt;
48
diff --git a/tests/qtest/migration/postcopy-tests.c b/tests/qtest/migration/postcopy-tests.c
67
diff --git a/tests/qtest/migration/postcopy-tests.c b/tests/qtest/migration/postcopy-tests.c
49
index XXXXXXX..XXXXXXX 100644
68
index XXXXXXX..XXXXXXX 100644
50
--- a/tests/qtest/migration/postcopy-tests.c
69
--- a/tests/qtest/migration/postcopy-tests.c
51
+++ b/tests/qtest/migration/postcopy-tests.c
70
+++ b/tests/qtest/migration/postcopy-tests.c
52
@@ -XXX,XX +XXX,XX @@ static void test_postcopy(void)
71
@@ -XXX,XX +XXX,XX @@ static void migration_test_add_postcopy_smoke(MigrationTestEnv *env)
53
test_postcopy_common(&args);
72
}
54
}
73
}
55
74
56
+static void test_postcopy_multifd(void)
75
+static void test_multifd_postcopy(void)
57
+{
76
+{
58
+ MigrateCommon args = {
77
+ MigrateCommon args = {
59
+ .multifd = true,
78
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
60
+ };
79
+ };
61
+
80
+
62
+ test_postcopy_common(&args);
81
+ test_postcopy_common(&args);
63
+}
82
+}
64
+
83
+
65
static void test_postcopy_suspend(void)
84
+static void test_multifd_postcopy_preempt(void)
66
{
85
+{
67
MigrateCommon args = {
86
+ MigrateCommon args = {
87
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
88
+ .caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT] = true,
89
+ };
90
+
91
+ test_postcopy_common(&args);
92
+}
93
+
94
void migration_test_add_postcopy(MigrationTestEnv *env)
95
{
96
migration_test_add_postcopy_smoke(env);
68
@@ -XXX,XX +XXX,XX @@ void migration_test_add_postcopy(MigrationTestEnv *env)
97
@@ -XXX,XX +XXX,XX @@ void migration_test_add_postcopy(MigrationTestEnv *env)
69
{
98
"/migration/postcopy/recovery/double-failures/reconnect",
70
if (env->has_uffd) {
99
test_postcopy_recovery_fail_reconnect);
71
migration_test_add("/migration/postcopy/plain", test_postcopy);
100
72
+ migration_test_add("/migration/postcopy/multifd", test_postcopy_multifd);
101
+ migration_test_add("/migration/multifd+postcopy/plain",
73
migration_test_add("/migration/postcopy/recovery/plain",
102
+ test_multifd_postcopy);
74
test_postcopy_recovery);
103
+ migration_test_add("/migration/multifd+postcopy/preempt/plain",
75
migration_test_add("/migration/postcopy/preempt/plain",
104
+ test_multifd_postcopy_preempt);
105
if (env->is_x86) {
106
migration_test_add("/migration/postcopy/suspend",
107
test_postcopy_suspend);
108
diff --git a/tests/qtest/migration/precopy-tests.c b/tests/qtest/migration/precopy-tests.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/tests/qtest/migration/precopy-tests.c
111
+++ b/tests/qtest/migration/precopy-tests.c
112
@@ -XXX,XX +XXX,XX @@
113
#define DIRTYLIMIT_TOLERANCE_RANGE 25 /* MB/s */
114
115
static char *tmpfs;
116
+static bool postcopy_ram = false;
117
118
static void test_precopy_unix_plain(void)
119
{
120
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_cancel(void)
121
migrate_ensure_non_converge(from);
122
migrate_prepare_for_dirty_mem(from);
123
124
+ if (postcopy_ram) {
125
+ migrate_set_capability(from, "postcopy-ram", true);
126
+ migrate_set_capability(to, "postcopy-ram", true);
127
+ }
128
+
129
migrate_set_parameter_int(from, "multifd-channels", 16);
130
migrate_set_parameter_int(to, "multifd-channels", 16);
131
132
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_cancel(void)
133
return;
134
}
135
136
+ if (postcopy_ram) {
137
+ migrate_set_capability(to2, "postcopy-ram", true);
138
+ }
139
+
140
migrate_set_parameter_int(to2, "multifd-channels", 16);
141
142
migrate_set_capability(to2, "multifd", true);
143
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_cancel(void)
144
migrate_end(from, to2, true);
145
}
146
147
+static void test_multifd_postcopy_tcp_cancel(void)
148
+{
149
+ postcopy_ram = true;
150
+ test_multifd_tcp_cancel();
151
+ postcopy_ram = false;
152
+}
153
+
154
static void calc_dirty_rate(QTestState *who, uint64_t calc_time)
155
{
156
qtest_qmp_assert_success(who,
157
@@ -XXX,XX +XXX,XX @@ void migration_test_add_precopy(MigrationTestEnv *env)
158
test_multifd_tcp_zero_page_legacy);
159
migration_test_add("/migration/multifd/tcp/plain/zero-page/none",
160
test_multifd_tcp_no_zero_page);
161
+ migration_test_add("migration/multifd+postcopy/tcp/plain/cancel",
162
+ test_multifd_postcopy_tcp_cancel);
163
if (g_str_equal(env->arch, "x86_64")
164
&& env->has_kvm && env->has_dirty_ring) {
165
166
diff --git a/tests/qtest/migration/tls-tests.c b/tests/qtest/migration/tls-tests.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/tests/qtest/migration/tls-tests.c
169
+++ b/tests/qtest/migration/tls-tests.c
170
@@ -XXX,XX +XXX,XX @@ static void test_postcopy_recovery_tls_psk(void)
171
test_postcopy_recovery_common(&args);
172
}
173
174
+static void test_multifd_postcopy_recovery_tls_psk(void)
175
+{
176
+ MigrateCommon args = {
177
+ .start_hook = migrate_hook_start_tls_psk_match,
178
+ .end_hook = migrate_hook_end_tls_psk,
179
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
180
+ };
181
+
182
+ test_postcopy_recovery_common(&args);
183
+}
184
+
185
/* This contains preempt+recovery+tls test altogether */
186
static void test_postcopy_preempt_all(void)
187
{
188
@@ -XXX,XX +XXX,XX @@ static void test_postcopy_preempt_all(void)
189
test_postcopy_recovery_common(&args);
190
}
191
192
+static void test_multifd_postcopy_preempt_recovery_tls_psk(void)
193
+{
194
+ MigrateCommon args = {
195
+ .start_hook = migrate_hook_start_tls_psk_match,
196
+ .end_hook = migrate_hook_end_tls_psk,
197
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
198
+ };
199
+
200
+ test_postcopy_recovery_common(&args);
201
+}
202
+
203
static void test_precopy_unix_tls_psk(void)
204
{
205
g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
206
@@ -XXX,XX +XXX,XX @@ static void test_multifd_tcp_tls_psk_mismatch(void)
207
test_precopy_common(&args);
208
}
209
210
+static void test_multifd_postcopy_tcp_tls_psk_match(void)
211
+{
212
+ MigrateCommon args = {
213
+ .listen_uri = "defer",
214
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
215
+ .start_hook = migrate_hook_start_multifd_tcp_tls_psk_match,
216
+ .end_hook = migrate_hook_end_tls_psk,
217
+ };
218
+
219
+ test_precopy_common(&args);
220
+}
221
+
222
#ifdef CONFIG_TASN1
223
static void test_multifd_tcp_tls_x509_default_host(void)
224
{
225
@@ -XXX,XX +XXX,XX @@ void migration_test_add_tls(MigrationTestEnv *env)
226
test_postcopy_preempt_tls_psk);
227
migration_test_add("/migration/postcopy/preempt/recovery/tls/psk",
228
test_postcopy_preempt_all);
229
+ migration_test_add("/migration/multifd+postcopy/recovery/tls/psk",
230
+ test_multifd_postcopy_recovery_tls_psk);
231
+ migration_test_add("/migration/multifd+postcopy/preempt/recovery/tls/psk",
232
+ test_multifd_postcopy_preempt_recovery_tls_psk);
233
}
234
#ifdef CONFIG_TASN1
235
migration_test_add("/migration/precopy/unix/tls/x509/default-host",
236
@@ -XXX,XX +XXX,XX @@ void migration_test_add_tls(MigrationTestEnv *env)
237
test_multifd_tcp_tls_psk_match);
238
migration_test_add("/migration/multifd/tcp/tls/psk/mismatch",
239
test_multifd_tcp_tls_psk_mismatch);
240
+ migration_test_add("/migration/multifd+postcopy/tcp/tls/psk/match",
241
+ test_multifd_postcopy_tcp_tls_psk_match);
242
#ifdef CONFIG_TASN1
243
migration_test_add("/migration/multifd/tcp/tls/x509/default-host",
244
test_multifd_tcp_tls_x509_default_host);
76
--
245
--
77
2.48.1
246
2.48.1
diff view generated by jsdifflib