* [PATCH v8 0/3] Eliminate multifd flush
@ 2023-04-25 16:31 Juan Quintela
2023-04-25 16:31 ` [PATCH v8 1/3] multifd: Create property multifd-flush-after-each-section Juan Quintela
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Juan Quintela @ 2023-04-25 16:31 UTC (permalink / raw)
To: qemu-devel
Cc: Yanan Wang, Marcel Apfelbaum, Juan Quintela,
Philippe Mathieu-Daudé, Peter Xu, Eduardo Habkost,
Leonardo Bras
Hi
In this v8:
- rebase over latests
Please review.
[v7]
- Rebased to last upstream
- Rename the capability to a property. So we move all the problems
that we have on last review dissaper because it is not a capability.
So now, it is works as expected. Enabled for old machine types,
disabled for new machine types. Users will only found it if they go through the migration properties.
Please review.
In this v6:
- Rename multifd-sync-after-each-section to
multifd-flush-after-each-section
- Redo comments (thanks Markus)
- Redo how to comment capabilities that are enabled/disabled during
development. (thanks Markus)
Please, review.
In this v5:
- Remove RAM Flags documentation (already on PULL request)
- rebase on top of PULL request.
Please review.
Based-on: <20230213025150.71537-1-quintela@redhat.com>
Migration 20230213 patches
In this v4:
- Rebased on top of migration-20230209 PULL request
- Integrate two patches in that pull request
- Rebase
- Address Eric reviews.
Please review.
In this v3:
- update to latest upstream.
- fix checkpatch errors.
Please, review.
In this v2:
- update to latest upstream
- change 0, 1, 2 values to defines
- Add documentation for SAVE_VM_FLAGS
- Add missing qemu_fflush(), it made random hangs for migration test
(only for tls, no clue why).
Please, review.
[v1]
Upstream multifd code synchronize all threads after each RAM section. This is suboptimal.
Change it to only flush after we go trough all ram.
Preserve all semantics for old machine types.
Juan Quintela (3):
multifd: Create property multifd-flush-after-each-section
multifd: Protect multifd_send_sync_main() calls
multifd: Only flush once each full round of memory
hw/core/machine.c | 1 +
migration/migration.c | 9 +++++++++
migration/migration.h | 12 ++++++++++++
migration/ram.c | 44 +++++++++++++++++++++++++++++++++++++------
4 files changed, 60 insertions(+), 6 deletions(-)
--
2.40.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v8 1/3] multifd: Create property multifd-flush-after-each-section
2023-04-25 16:31 [PATCH v8 0/3] Eliminate multifd flush Juan Quintela
@ 2023-04-25 16:31 ` Juan Quintela
2023-04-25 18:42 ` Peter Xu
2023-04-25 16:31 ` [PATCH v8 2/3] multifd: Protect multifd_send_sync_main() calls Juan Quintela
` (2 subsequent siblings)
3 siblings, 1 reply; 7+ messages in thread
From: Juan Quintela @ 2023-04-25 16:31 UTC (permalink / raw)
To: qemu-devel
Cc: Yanan Wang, Marcel Apfelbaum, Juan Quintela,
Philippe Mathieu-Daudé, Peter Xu, Eduardo Habkost,
Leonardo Bras, Dr . David Alan Gilbert
We used to flush all channels at the end of each RAM section
sent. That is not needed, so preparing to only flush after a full
iteration through all the RAM.
Default value of the property is false. But we return "true" in
migrate_multifd_flush_after_each_section() until we implement the code
in following patches.
Signed-off-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
Rename each-iteration to after-each-section
Rename multifd-sync-after-each-section to
multifd-flush-after-each-section
---
hw/core/machine.c | 1 +
migration/migration.c | 13 +++++++++++++
migration/migration.h | 13 +++++++++++++
3 files changed, 27 insertions(+)
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 2ce97a5d3b..32bd9277b3 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -60,6 +60,7 @@ const size_t hw_compat_7_1_len = G_N_ELEMENTS(hw_compat_7_1);
GlobalProperty hw_compat_7_0[] = {
{ "arm-gicv3-common", "force-8-bit-prio", "on" },
{ "nvme-ns", "eui64-default", "on"},
+ { "migration", "multifd-flush-after-each-section", "on"},
};
const size_t hw_compat_7_0_len = G_N_ELEMENTS(hw_compat_7_0);
diff --git a/migration/migration.c b/migration/migration.c
index d91fe9fd86..4b94360f05 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2697,6 +2697,17 @@ bool migrate_use_multifd(void)
return s->capabilities[MIGRATION_CAPABILITY_MULTIFD];
}
+bool migrate_multifd_flush_after_each_section(void)
+{
+ MigrationState *s = migrate_get_current();
+
+ /*
+ * Until the patch that remove this comment, we always return that
+ * the property is enabled.
+ */
+ return true || s->multifd_flush_after_each_section;
+}
+
bool migrate_pause_before_switchover(void)
{
MigrationState *s;
@@ -4448,6 +4459,8 @@ static Property migration_properties[] = {
send_section_footer, true),
DEFINE_PROP_BOOL("decompress-error-check", MigrationState,
decompress_error_check, true),
+ DEFINE_PROP_BOOL("multifd-flush-after-each-section", MigrationState,
+ multifd_flush_after_each_section, true),
DEFINE_PROP_UINT8("x-clear-bitmap-shift", MigrationState,
clear_bitmap_shift, CLEAR_BITMAP_SHIFT_DEFAULT),
DEFINE_PROP_BOOL("x-preempt-pre-7-2", MigrationState,
diff --git a/migration/migration.h b/migration/migration.h
index 04e0860b4e..50b4006e93 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -404,6 +404,18 @@ struct MigrationState {
*/
bool preempt_pre_7_2;
+ /*
+ * flush every channel after each section sent.
+ *
+ * This assures that we can't mix pages from one iteration through
+ * ram pages with pages for the following iteration. We really
+ * only need to do this flush after we have go through all the
+ * dirty pages. For historical reasons, we do that after each
+ * section. This is suboptimal (we flush too many times).
+ * Default value is false. Setting this property has no effect
+ * until the patch that removes this comment. (since 8.1)
+ */
+ bool multifd_flush_after_each_section;
/*
* This decides the size of guest memory chunk that will be used
* to track dirty bitmap clearing. The size of memory chunk will
@@ -463,6 +475,7 @@ int migrate_multifd_channels(void);
MultiFDCompression migrate_multifd_compression(void);
int migrate_multifd_zlib_level(void);
int migrate_multifd_zstd_level(void);
+bool migrate_multifd_flush_after_each_section(void);
#ifdef CONFIG_LINUX
bool migrate_use_zero_copy_send(void);
--
2.40.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v8 2/3] multifd: Protect multifd_send_sync_main() calls
2023-04-25 16:31 [PATCH v8 0/3] Eliminate multifd flush Juan Quintela
2023-04-25 16:31 ` [PATCH v8 1/3] multifd: Create property multifd-flush-after-each-section Juan Quintela
@ 2023-04-25 16:31 ` Juan Quintela
2023-04-25 16:31 ` [PATCH v8 3/3] multifd: Only flush once each full round of memory Juan Quintela
2023-04-25 18:49 ` [PATCH v8 0/3] Eliminate multifd flush Peter Xu
3 siblings, 0 replies; 7+ messages in thread
From: Juan Quintela @ 2023-04-25 16:31 UTC (permalink / raw)
To: qemu-devel
Cc: Yanan Wang, Marcel Apfelbaum, Juan Quintela,
Philippe Mathieu-Daudé, Peter Xu, Eduardo Habkost,
Leonardo Bras, Dr . David Alan Gilbert
We only need to do that on the ram_save_iterate() call on sending and
on destination when we get a RAM_SAVE_FLAG_EOS.
In setup() and complete() we need to synch in both new and old cases,
so don't add a check there.
Signed-off-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
Remove the wrappers that we take out on patch 5.
---
migration/ram.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/migration/ram.c b/migration/ram.c
index 229714045a..93ff9988e3 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -3395,9 +3395,11 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
out:
if (ret >= 0
&& migration_is_setup_or_active(migrate_get_current()->state)) {
- ret = multifd_send_sync_main(rs->pss[RAM_CHANNEL_PRECOPY].pss_channel);
- if (ret < 0) {
- return ret;
+ if (migrate_multifd_flush_after_each_section()) {
+ ret = multifd_send_sync_main(rs->pss[RAM_CHANNEL_PRECOPY].pss_channel);
+ if (ret < 0) {
+ return ret;
+ }
}
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
@@ -4154,7 +4156,9 @@ int ram_load_postcopy(QEMUFile *f, int channel)
case RAM_SAVE_FLAG_EOS:
/* normal exit */
- multifd_recv_sync_main();
+ if (migrate_multifd_flush_after_each_section()) {
+ multifd_recv_sync_main();
+ }
break;
default:
error_report("Unknown combination of migration flags: 0x%x"
@@ -4425,7 +4429,9 @@ static int ram_load_precopy(QEMUFile *f)
break;
case RAM_SAVE_FLAG_EOS:
/* normal exit */
- multifd_recv_sync_main();
+ if (migrate_multifd_flush_after_each_section()) {
+ multifd_recv_sync_main();
+ }
break;
default:
if (flags & RAM_SAVE_FLAG_HOOK) {
--
2.40.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v8 3/3] multifd: Only flush once each full round of memory
2023-04-25 16:31 [PATCH v8 0/3] Eliminate multifd flush Juan Quintela
2023-04-25 16:31 ` [PATCH v8 1/3] multifd: Create property multifd-flush-after-each-section Juan Quintela
2023-04-25 16:31 ` [PATCH v8 2/3] multifd: Protect multifd_send_sync_main() calls Juan Quintela
@ 2023-04-25 16:31 ` Juan Quintela
2023-04-25 18:49 ` [PATCH v8 0/3] Eliminate multifd flush Peter Xu
3 siblings, 0 replies; 7+ messages in thread
From: Juan Quintela @ 2023-04-25 16:31 UTC (permalink / raw)
To: qemu-devel
Cc: Yanan Wang, Marcel Apfelbaum, Juan Quintela,
Philippe Mathieu-Daudé, Peter Xu, Eduardo Habkost,
Leonardo Bras
We need to add a new flag to mean to flush at that point.
Notice that we still flush at the end of setup and at the end of
complete stages.
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
Add missing qemu_fflush(), now it passes all tests always.
---
migration/migration.c | 6 +-----
migration/migration.h | 3 +--
migration/ram.c | 28 +++++++++++++++++++++++++++-
3 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index 4b94360f05..2bc706a8e2 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2701,11 +2701,7 @@ bool migrate_multifd_flush_after_each_section(void)
{
MigrationState *s = migrate_get_current();
- /*
- * Until the patch that remove this comment, we always return that
- * the property is enabled.
- */
- return true || s->multifd_flush_after_each_section;
+ return s->multifd_flush_after_each_section;
}
bool migrate_pause_before_switchover(void)
diff --git a/migration/migration.h b/migration/migration.h
index 50b4006e93..731b352807 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -412,8 +412,7 @@ struct MigrationState {
* only need to do this flush after we have go through all the
* dirty pages. For historical reasons, we do that after each
* section. This is suboptimal (we flush too many times).
- * Default value is false. Setting this property has no effect
- * until the patch that removes this comment. (since 8.1)
+ * Default value is false. (since 8.1)
*/
bool multifd_flush_after_each_section;
/*
diff --git a/migration/ram.c b/migration/ram.c
index 93ff9988e3..a4333a1bc2 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -85,6 +85,7 @@
#define RAM_SAVE_FLAG_XBZRLE 0x40
/* 0x80 is reserved in qemu-file.h for RAM_SAVE_FLAG_HOOK */
#define RAM_SAVE_FLAG_COMPRESS_PAGE 0x100
+#define RAM_SAVE_FLAG_MULTIFD_FLUSH 0x200
/* We can't use any flag that is bigger than 0x200 */
int (*xbzrle_encode_buffer_func)(uint8_t *, uint8_t *, int,
@@ -1582,6 +1583,7 @@ retry:
* associated with the search process.
*
* Returns:
+ * <0: An error happened
* PAGE_ALL_CLEAN: no dirty page found, give up
* PAGE_TRY_AGAIN: no dirty page found, retry for next block
* PAGE_DIRTY_FOUND: dirty page found
@@ -1609,6 +1611,15 @@ static int find_dirty_block(RAMState *rs, PageSearchStatus *pss)
pss->page = 0;
pss->block = QLIST_NEXT_RCU(pss->block, next);
if (!pss->block) {
+ if (!migrate_multifd_flush_after_each_section()) {
+ QEMUFile *f = rs->pss[RAM_CHANNEL_PRECOPY].pss_channel;
+ int ret = multifd_send_sync_main(f);
+ if (ret < 0) {
+ return ret;
+ }
+ qemu_put_be64(f, RAM_SAVE_FLAG_MULTIFD_FLUSH);
+ qemu_fflush(f);
+ }
/*
* If memory migration starts over, we will meet a dirtied page
* which may still exists in compression threads's ring, so we
@@ -2601,6 +2612,9 @@ static int ram_find_and_save_block(RAMState *rs)
break;
} else if (res == PAGE_TRY_AGAIN) {
continue;
+ } else if (res < 0) {
+ pages = res;
+ break;
}
}
}
@@ -3287,6 +3301,10 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
return ret;
}
+ if (!migrate_multifd_flush_after_each_section()) {
+ qemu_put_be64(f, RAM_SAVE_FLAG_MULTIFD_FLUSH);
+ }
+
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
qemu_fflush(f);
@@ -3472,6 +3490,9 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
return ret;
}
+ if (!migrate_multifd_flush_after_each_section()) {
+ qemu_put_be64(f, RAM_SAVE_FLAG_MULTIFD_FLUSH);
+ }
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
qemu_fflush(f);
@@ -4153,7 +4174,9 @@ int ram_load_postcopy(QEMUFile *f, int channel)
}
decompress_data_with_multi_threads(f, page_buffer, len);
break;
-
+ case RAM_SAVE_FLAG_MULTIFD_FLUSH:
+ multifd_recv_sync_main();
+ break;
case RAM_SAVE_FLAG_EOS:
/* normal exit */
if (migrate_multifd_flush_after_each_section()) {
@@ -4427,6 +4450,9 @@ static int ram_load_precopy(QEMUFile *f)
break;
}
break;
+ case RAM_SAVE_FLAG_MULTIFD_FLUSH:
+ multifd_recv_sync_main();
+ break;
case RAM_SAVE_FLAG_EOS:
/* normal exit */
if (migrate_multifd_flush_after_each_section()) {
--
2.40.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v8 1/3] multifd: Create property multifd-flush-after-each-section
2023-04-25 16:31 ` [PATCH v8 1/3] multifd: Create property multifd-flush-after-each-section Juan Quintela
@ 2023-04-25 18:42 ` Peter Xu
2023-04-26 16:55 ` Juan Quintela
0 siblings, 1 reply; 7+ messages in thread
From: Peter Xu @ 2023-04-25 18:42 UTC (permalink / raw)
To: Juan Quintela
Cc: qemu-devel, Yanan Wang, Marcel Apfelbaum,
Philippe Mathieu-Daudé, Eduardo Habkost, Leonardo Bras,
Dr . David Alan Gilbert
On Tue, Apr 25, 2023 at 06:31:12PM +0200, Juan Quintela wrote:
> We used to flush all channels at the end of each RAM section
> sent. That is not needed, so preparing to only flush after a full
> iteration through all the RAM.
>
> Default value of the property is false. But we return "true" in
> migrate_multifd_flush_after_each_section() until we implement the code
> in following patches.
>
> Signed-off-by: Juan Quintela <quintela@redhat.com>
> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> Signed-off-by: Juan Quintela <quintela@redhat.com>
PS: Normally I'll just keep the last Sign-off-by for each person. :)
>
> ---
>
> Rename each-iteration to after-each-section
> Rename multifd-sync-after-each-section to
> multifd-flush-after-each-section
> ---
> hw/core/machine.c | 1 +
> migration/migration.c | 13 +++++++++++++
> migration/migration.h | 13 +++++++++++++
> 3 files changed, 27 insertions(+)
>
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 2ce97a5d3b..32bd9277b3 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -60,6 +60,7 @@ const size_t hw_compat_7_1_len = G_N_ELEMENTS(hw_compat_7_1);
> GlobalProperty hw_compat_7_0[] = {
> { "arm-gicv3-common", "force-8-bit-prio", "on" },
> { "nvme-ns", "eui64-default", "on"},
> + { "migration", "multifd-flush-after-each-section", "on"},
> };
Here we need hw_compat_8_0 instead?
Thanks,
--
Peter Xu
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v8 0/3] Eliminate multifd flush
2023-04-25 16:31 [PATCH v8 0/3] Eliminate multifd flush Juan Quintela
` (2 preceding siblings ...)
2023-04-25 16:31 ` [PATCH v8 3/3] multifd: Only flush once each full round of memory Juan Quintela
@ 2023-04-25 18:49 ` Peter Xu
3 siblings, 0 replies; 7+ messages in thread
From: Peter Xu @ 2023-04-25 18:49 UTC (permalink / raw)
To: Juan Quintela
Cc: qemu-devel, Yanan Wang, Marcel Apfelbaum,
Philippe Mathieu-Daudé, Eduardo Habkost, Leonardo Bras
On Tue, Apr 25, 2023 at 06:31:11PM +0200, Juan Quintela wrote:
> Hi
>
> In this v8:
> - rebase over latests
One trivial comment for patch 1 on the compat bits, for patch 2-3:
Acked-by: Peter Xu <peterx@redhat.com>
Nit: I still think we should just squash the three patches into one, but
I'm fine either way.
Thanks,
--
Peter Xu
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v8 1/3] multifd: Create property multifd-flush-after-each-section
2023-04-25 18:42 ` Peter Xu
@ 2023-04-26 16:55 ` Juan Quintela
0 siblings, 0 replies; 7+ messages in thread
From: Juan Quintela @ 2023-04-26 16:55 UTC (permalink / raw)
To: Peter Xu
Cc: qemu-devel, Yanan Wang, Marcel Apfelbaum,
Philippe Mathieu-Daudé, Eduardo Habkost, Leonardo Bras,
Dr . David Alan Gilbert
Peter Xu <peterx@redhat.com> wrote:
> On Tue, Apr 25, 2023 at 06:31:12PM +0200, Juan Quintela wrote:
>> We used to flush all channels at the end of each RAM section
>> sent. That is not needed, so preparing to only flush after a full
>> iteration through all the RAM.
>>
>> Default value of the property is false. But we return "true" in
>> migrate_multifd_flush_after_each_section() until we implement the code
>> in following patches.
>>
>> Signed-off-by: Juan Quintela <quintela@redhat.com>
>> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
>> Signed-off-by: Juan Quintela <quintela@redhat.com>
>
> PS: Normally I'll just keep the last Sign-off-by for each person. :)
And here we are again O:-)
I have a hook to put that in. And at some point it did the wrong thing
(i.e. this), and I always forgot to look into old series for this error.
Sorry, fixed.
>>
>> ---
>>
>> Rename each-iteration to after-each-section
>> Rename multifd-sync-after-each-section to
>> multifd-flush-after-each-section
>> ---
>> hw/core/machine.c | 1 +
>> migration/migration.c | 13 +++++++++++++
>> migration/migration.h | 13 +++++++++++++
>> 3 files changed, 27 insertions(+)
>>
>> diff --git a/hw/core/machine.c b/hw/core/machine.c
>> index 2ce97a5d3b..32bd9277b3 100644
>> --- a/hw/core/machine.c
>> +++ b/hw/core/machine.c
>> @@ -60,6 +60,7 @@ const size_t hw_compat_7_1_len = G_N_ELEMENTS(hw_compat_7_1);
>> GlobalProperty hw_compat_7_0[] = {
>> { "arm-gicv3-common", "force-8-bit-prio", "on" },
>> { "nvme-ns", "eui64-default", "on"},
>> + { "migration", "multifd-flush-after-each-section", "on"},
>> };
>
> Here we need hw_compat_8_0 instead?
Good catch.
Changed.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2023-04-26 16:56 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-25 16:31 [PATCH v8 0/3] Eliminate multifd flush Juan Quintela
2023-04-25 16:31 ` [PATCH v8 1/3] multifd: Create property multifd-flush-after-each-section Juan Quintela
2023-04-25 18:42 ` Peter Xu
2023-04-26 16:55 ` Juan Quintela
2023-04-25 16:31 ` [PATCH v8 2/3] multifd: Protect multifd_send_sync_main() calls Juan Quintela
2023-04-25 16:31 ` [PATCH v8 3/3] multifd: Only flush once each full round of memory Juan Quintela
2023-04-25 18:49 ` [PATCH v8 0/3] Eliminate multifd flush Peter Xu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).