From d2026ee117147893f8d80f060cede6d872ecbd7f Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Wed, 26 Apr 2023 12:20:36 +0200 Subject: [PATCH 01/18] multifd: Fix the number of channels ready We don't wait in the sem when we are doing a sync_main. Make it wait there. To make things clearer, we mark the channel ready at the begining of the thread loop. Signed-off-by: Juan Quintela Reviewed-by: Fabiano Rosas --- migration/multifd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/migration/multifd.c b/migration/multifd.c index cce3ad6988..6a59c03dd2 100644 --- a/migration/multifd.c +++ b/migration/multifd.c @@ -635,6 +635,7 @@ int multifd_send_sync_main(QEMUFile *f) for (i = 0; i < migrate_multifd_channels(); i++) { MultiFDSendParams *p = &multifd_send_state->params[i]; + qemu_sem_wait(&multifd_send_state->channels_ready); trace_multifd_send_sync_main_wait(p->id); qemu_sem_wait(&p->sem_sync); @@ -668,6 +669,7 @@ static void *multifd_send_thread(void *opaque) p->num_packets = 1; while (true) { + qemu_sem_post(&multifd_send_state->channels_ready); qemu_sem_wait(&p->sem); if (qatomic_read(&multifd_send_state->exiting)) { @@ -736,7 +738,6 @@ static void *multifd_send_thread(void *opaque) if (flags & MULTIFD_FLAG_SYNC) { qemu_sem_post(&p->sem_sync); } - qemu_sem_post(&multifd_send_state->channels_ready); } else if (p->quit) { qemu_mutex_unlock(&p->mutex); break; From 61a174e227422790f1b264fed6df5c6686757edc Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Thu, 2 Mar 2023 10:35:24 +0100 Subject: [PATCH 02/18] migration: Create migrate_params_init() function Signed-off-by: Juan Quintela Reviewed-by: Vladimir Sementsov-Ogievskiy --- migration/migration.c | 29 +---------------------------- migration/options.c | 31 +++++++++++++++++++++++++++++++ migration/options.h | 1 + 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index 22e8586623..45fc5be93a 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -3470,7 +3470,6 @@ static void migration_instance_finalize(Object *obj) static void migration_instance_init(Object *obj) { MigrationState *ms = MIGRATION_OBJ(obj); - MigrationParameters *params = &ms->parameters; ms->state = MIGRATION_STATUS_NONE; ms->mbps = -1; @@ -3478,33 +3477,7 @@ static void migration_instance_init(Object *obj) qemu_sem_init(&ms->pause_sem, 0); qemu_mutex_init(&ms->error_mutex); - params->tls_hostname = g_strdup(""); - params->tls_creds = g_strdup(""); - - /* Set has_* up only for parameter checks */ - params->has_compress_level = true; - params->has_compress_threads = true; - params->has_compress_wait_thread = true; - params->has_decompress_threads = true; - params->has_throttle_trigger_threshold = true; - params->has_cpu_throttle_initial = true; - params->has_cpu_throttle_increment = true; - params->has_cpu_throttle_tailslow = true; - params->has_max_bandwidth = true; - params->has_downtime_limit = true; - params->has_x_checkpoint_delay = true; - params->has_block_incremental = true; - params->has_multifd_channels = true; - params->has_multifd_compression = true; - params->has_multifd_zlib_level = true; - params->has_multifd_zstd_level = true; - params->has_xbzrle_cache_size = true; - params->has_max_postcopy_bandwidth = true; - params->has_max_cpu_throttle = true; - params->has_announce_initial = true; - params->has_announce_max = true; - params->has_announce_rounds = true; - params->has_announce_step = true; + migrate_params_init(&ms->parameters); qemu_sem_init(&ms->postcopy_pause_sem, 0); qemu_sem_init(&ms->postcopy_pause_rp_sem, 0); diff --git a/migration/options.c b/migration/options.c index c6030587cf..552e8d8e5c 100644 --- a/migration/options.c +++ b/migration/options.c @@ -741,6 +741,37 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp) return params; } +void migrate_params_init(MigrationParameters *params) +{ + params->tls_hostname = g_strdup(""); + params->tls_creds = g_strdup(""); + + /* Set has_* up only for parameter checks */ + params->has_compress_level = true; + params->has_compress_threads = true; + params->has_compress_wait_thread = true; + params->has_decompress_threads = true; + params->has_throttle_trigger_threshold = true; + params->has_cpu_throttle_initial = true; + params->has_cpu_throttle_increment = true; + params->has_cpu_throttle_tailslow = true; + params->has_max_bandwidth = true; + params->has_downtime_limit = true; + params->has_x_checkpoint_delay = true; + params->has_block_incremental = true; + params->has_multifd_channels = true; + params->has_multifd_compression = true; + params->has_multifd_zlib_level = true; + params->has_multifd_zstd_level = true; + params->has_xbzrle_cache_size = true; + params->has_max_postcopy_bandwidth = true; + params->has_max_cpu_throttle = true; + params->has_announce_initial = true; + params->has_announce_max = true; + params->has_announce_rounds = true; + params->has_announce_step = true; +} + /* * Check whether the parameters are valid. Error will be put into errp * (if provided). Return true if valid, otherwise false. diff --git a/migration/options.h b/migration/options.h index 89067e59a0..86bcbb738c 100644 --- a/migration/options.h +++ b/migration/options.h @@ -84,5 +84,6 @@ uint64_t migrate_xbzrle_cache_size(void); /* parameters helpers */ bool migrate_params_check(MigrationParameters *params, Error **errp); +void migrate_params_init(MigrationParameters *params); #endif From 8f9c532756c598c29282a1ec2f11fb615e2fd3c7 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Wed, 1 Mar 2023 23:11:08 +0100 Subject: [PATCH 03/18] migration: Make all functions check have the same format Signed-off-by: Juan Quintela Reviewed-by: Vladimir Sementsov-Ogievskiy --- migration/options.c | 153 +++++++++++--------------------------------- 1 file changed, 39 insertions(+), 114 deletions(-) diff --git a/migration/options.c b/migration/options.c index 552e8d8e5c..0b1b56e68f 100644 --- a/migration/options.c +++ b/migration/options.c @@ -33,27 +33,21 @@ bool migrate_auto_converge(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE]; } bool migrate_background_snapshot(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]; } bool migrate_block(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->capabilities[MIGRATION_CAPABILITY_BLOCK]; } @@ -61,95 +55,76 @@ bool migrate_block(void) bool migrate_colo(void) { MigrationState *s = migrate_get_current(); + return s->capabilities[MIGRATION_CAPABILITY_X_COLO]; } bool migrate_compress(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->capabilities[MIGRATION_CAPABILITY_COMPRESS]; } bool migrate_dirty_bitmaps(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS]; } bool migrate_events(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->capabilities[MIGRATION_CAPABILITY_EVENTS]; } bool migrate_ignore_shared(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED]; } bool migrate_late_block_activate(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->capabilities[MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE]; } bool migrate_multifd(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->capabilities[MIGRATION_CAPABILITY_MULTIFD]; } bool migrate_pause_before_switchover(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->capabilities[MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER]; } bool migrate_postcopy_blocktime(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME]; } bool migrate_postcopy_preempt(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]; } bool migrate_postcopy_ram(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM]; } @@ -163,54 +138,42 @@ bool migrate_rdma_pin_all(void) bool migrate_release_ram(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->capabilities[MIGRATION_CAPABILITY_RELEASE_RAM]; } bool migrate_return_path(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->capabilities[MIGRATION_CAPABILITY_RETURN_PATH]; } bool migrate_validate_uuid(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID]; } bool migrate_xbzrle(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->capabilities[MIGRATION_CAPABILITY_XBZRLE]; } bool migrate_zero_blocks(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS]; } bool migrate_zero_copy_send(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND]; } @@ -224,9 +187,7 @@ bool migrate_postcopy(void) bool migrate_tls(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->parameters.tls_creds && *s->parameters.tls_creds; } @@ -496,126 +457,98 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, bool migrate_block_incremental(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->parameters.block_incremental; } uint32_t migrate_checkpoint_delay(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->parameters.x_checkpoint_delay; } int migrate_compress_level(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->parameters.compress_level; } int migrate_compress_threads(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->parameters.compress_threads; } int migrate_compress_wait_thread(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->parameters.compress_wait_thread; } uint8_t migrate_cpu_throttle_increment(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->parameters.cpu_throttle_increment; } uint8_t migrate_cpu_throttle_initial(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->parameters.cpu_throttle_initial; } bool migrate_cpu_throttle_tailslow(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->parameters.cpu_throttle_tailslow; } int migrate_decompress_threads(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->parameters.decompress_threads; } uint8_t migrate_max_cpu_throttle(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->parameters.max_cpu_throttle; } uint64_t migrate_max_bandwidth(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->parameters.max_bandwidth; } int64_t migrate_max_postcopy_bandwidth(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->parameters.max_postcopy_bandwidth; } int migrate_multifd_channels(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->parameters.multifd_channels; } MultiFDCompression migrate_multifd_compression(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX); return s->parameters.multifd_compression; @@ -623,36 +556,28 @@ MultiFDCompression migrate_multifd_compression(void) int migrate_multifd_zlib_level(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->parameters.multifd_zlib_level; } int migrate_multifd_zstd_level(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->parameters.multifd_zstd_level; } uint8_t migrate_throttle_trigger_threshold(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->parameters.throttle_trigger_threshold; } uint64_t migrate_xbzrle_cache_size(void) { - MigrationState *s; - - s = migrate_get_current(); + MigrationState *s = migrate_get_current(); return s->parameters.xbzrle_cache_size; } From f5da8ba4777f3ab88bfee82bbf8261d6295a26a2 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Thu, 2 Mar 2023 12:00:43 +0100 Subject: [PATCH 04/18] migration: Create migrate_downtime_limit() function Signed-off-by: Juan Quintela Reviewed-by: Vladimir Sementsov-Ogievskiy --- migration/migration.c | 4 ++-- migration/options.c | 7 +++++++ migration/options.h | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index 45fc5be93a..ee8e9416ce 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -2737,7 +2737,7 @@ static void migration_update_counters(MigrationState *s, transferred = current_bytes - s->iteration_initial_bytes; time_spent = current_time - s->iteration_start_time; bandwidth = (double)transferred / time_spent; - s->threshold_size = bandwidth * s->parameters.downtime_limit; + s->threshold_size = bandwidth * migrate_downtime_limit(); s->mbps = (((double) transferred * 8.0) / ((double) time_spent / 1000.0)) / 1000.0 / 1000.0; @@ -3244,7 +3244,7 @@ void migrate_fd_connect(MigrationState *s, Error *error_in) */ migrate_error_free(s); - s->expected_downtime = s->parameters.downtime_limit; + s->expected_downtime = migrate_downtime_limit(); if (resume) { assert(s->cleanup_bh); } else { diff --git a/migration/options.c b/migration/options.c index 0b1b56e68f..f4ffe99603 100644 --- a/migration/options.c +++ b/migration/options.c @@ -518,6 +518,13 @@ int migrate_decompress_threads(void) return s->parameters.decompress_threads; } +uint64_t migrate_downtime_limit(void) +{ + MigrationState *s = migrate_get_current(); + + return s->parameters.downtime_limit; +} + uint8_t migrate_max_cpu_throttle(void) { MigrationState *s = migrate_get_current(); diff --git a/migration/options.h b/migration/options.h index 86bcbb738c..e982103c0d 100644 --- a/migration/options.h +++ b/migration/options.h @@ -71,6 +71,7 @@ uint8_t migrate_cpu_throttle_increment(void); uint8_t migrate_cpu_throttle_initial(void); bool migrate_cpu_throttle_tailslow(void); int migrate_decompress_threads(void); +uint64_t migrate_downtime_limit(void); uint8_t migrate_max_cpu_throttle(void); uint64_t migrate_max_bandwidth(void); int64_t migrate_max_postcopy_bandwidth(void); From 87c22901094a911e687e2ad014be868a9723c486 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Thu, 2 Mar 2023 12:05:03 +0100 Subject: [PATCH 05/18] migration: Move migrate_set_block_incremental() to options.c Once there, make it more regular and remove the need for MigrationState parameter. Signed-off-by: Juan Quintela Reviewed-by: Vladimir Sementsov-Ogievskiy --- migration/migration.c | 9 ++------- migration/options.c | 9 +++++++++ migration/options.h | 4 ++++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index ee8e9416ce..9a42f73aeb 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -1164,17 +1164,12 @@ void migrate_set_state(int *state, int old_state, int new_state) } } -static void migrate_set_block_incremental(MigrationState *s, bool value) -{ - s->parameters.block_incremental = value; -} - static void block_cleanup_parameters(MigrationState *s) { if (s->must_remove_block_options) { /* setting to false can never fail */ migrate_cap_set(MIGRATION_CAPABILITY_BLOCK, false, &error_abort); - migrate_set_block_incremental(s, false); + migrate_set_block_incremental(false); s->must_remove_block_options = false; } } @@ -1668,7 +1663,7 @@ static bool migrate_prepare(MigrationState *s, bool blk, bool blk_inc, } if (blk_inc) { - migrate_set_block_incremental(s, true); + migrate_set_block_incremental(true); } migrate_init(s); diff --git a/migration/options.c b/migration/options.c index f4ffe99603..89508d91a3 100644 --- a/migration/options.c +++ b/migration/options.c @@ -589,6 +589,15 @@ uint64_t migrate_xbzrle_cache_size(void) return s->parameters.xbzrle_cache_size; } +/* parameter setters */ + +void migrate_set_block_incremental(bool value) +{ + MigrationState *s = migrate_get_current(); + + s->parameters.block_incremental = value; +} + /* parameters helpers */ AnnounceParameters *migrate_announce_params(void) diff --git a/migration/options.h b/migration/options.h index e982103c0d..d261a25441 100644 --- a/migration/options.h +++ b/migration/options.h @@ -82,6 +82,10 @@ int migrate_multifd_zstd_level(void); uint8_t migrate_throttle_trigger_threshold(void); uint64_t migrate_xbzrle_cache_size(void); +/* parameters setters */ + +void migrate_set_block_incremental(bool value); + /* parameters helpers */ bool migrate_params_check(MigrationParameters *params, Error **errp); From b7b73122dd12b5fea63347253b428a9af66303c2 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Thu, 2 Mar 2023 12:08:45 +0100 Subject: [PATCH 06/18] migration: Move block_cleanup_parameters() to options.c Signed-off-by: Juan Quintela Reviewed-by: Vladimir Sementsov-Ogievskiy --- migration/migration.c | 10 ---------- migration/options.c | 10 ++++++++++ migration/options.h | 1 + 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index 9a42f73aeb..cefe6da2b8 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -1164,16 +1164,6 @@ void migrate_set_state(int *state, int old_state, int new_state) } } -static void block_cleanup_parameters(MigrationState *s) -{ - if (s->must_remove_block_options) { - /* setting to false can never fail */ - migrate_cap_set(MIGRATION_CAPABILITY_BLOCK, false, &error_abort); - migrate_set_block_incremental(false); - s->must_remove_block_options = false; - } -} - static void migrate_fd_cleanup(MigrationState *s) { qemu_bh_delete(s->cleanup_bh); diff --git a/migration/options.c b/migration/options.c index 89508d91a3..82adbf35b0 100644 --- a/migration/options.c +++ b/migration/options.c @@ -600,6 +600,16 @@ void migrate_set_block_incremental(bool value) /* parameters helpers */ +void block_cleanup_parameters(MigrationState *s) +{ + if (s->must_remove_block_options) { + /* setting to false can never fail */ + migrate_cap_set(MIGRATION_CAPABILITY_BLOCK, false, &error_abort); + migrate_set_block_incremental(false); + s->must_remove_block_options = false; + } +} + AnnounceParameters *migrate_announce_params(void) { static AnnounceParameters ap; diff --git a/migration/options.h b/migration/options.h index d261a25441..1fc8d341dd 100644 --- a/migration/options.h +++ b/migration/options.h @@ -90,5 +90,6 @@ void migrate_set_block_incremental(bool value); bool migrate_params_check(MigrationParameters *params, Error **errp); void migrate_params_init(MigrationParameters *params); +void block_cleanup_parameters(MigrationState *s); #endif From b1a8795654561b23eaf5bb134b61e5b23545046d Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Thu, 2 Mar 2023 12:10:33 +0100 Subject: [PATCH 07/18] migration: Remove MigrationState from block_cleanup_parameters() This makes the function more regular with everything else. Signed-off-by: Juan Quintela Reviewed-by: Vladimir Sementsov-Ogievskiy --- migration/migration.c | 4 ++-- migration/options.c | 4 +++- migration/options.h | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index cefe6da2b8..ef8caa79b9 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -1218,7 +1218,7 @@ static void migrate_fd_cleanup(MigrationState *s) error_report_err(error_copy(s->error)); } notifier_list_notify(&migration_state_notifiers, s); - block_cleanup_parameters(s); + block_cleanup_parameters(); yank_unregister_instance(MIGRATION_YANK_INSTANCE); } @@ -1712,7 +1712,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, "a valid migration protocol"); migrate_set_state(&s->state, MIGRATION_STATUS_SETUP, MIGRATION_STATUS_FAILED); - block_cleanup_parameters(s); + block_cleanup_parameters(); return; } diff --git a/migration/options.c b/migration/options.c index 82adbf35b0..da99c6298f 100644 --- a/migration/options.c +++ b/migration/options.c @@ -600,8 +600,10 @@ void migrate_set_block_incremental(bool value) /* parameters helpers */ -void block_cleanup_parameters(MigrationState *s) +void block_cleanup_parameters(void) { + MigrationState *s = migrate_get_current(); + if (s->must_remove_block_options) { /* setting to false can never fail */ migrate_cap_set(MIGRATION_CAPABILITY_BLOCK, false, &error_abort); diff --git a/migration/options.h b/migration/options.h index 1fc8d341dd..3948218dbe 100644 --- a/migration/options.h +++ b/migration/options.h @@ -90,6 +90,6 @@ void migrate_set_block_incremental(bool value); bool migrate_params_check(MigrationParameters *params, Error **errp); void migrate_params_init(MigrationParameters *params); -void block_cleanup_parameters(MigrationState *s); +void block_cleanup_parameters(void); #endif From d5c3e1959cbabe9456bf1d5860ad718c6cd27fb8 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Thu, 2 Mar 2023 12:17:06 +0100 Subject: [PATCH 08/18] migration: Create migrate_tls_creds() function Signed-off-by: Juan Quintela Reviewed-by: Vladimir Sementsov-Ogievskiy --- Moved the type to const char * (vladimir) --- migration/options.c | 7 +++++++ migration/options.h | 1 + migration/tls.c | 9 ++++----- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/migration/options.c b/migration/options.c index da99c6298f..b5d4ebef8d 100644 --- a/migration/options.c +++ b/migration/options.c @@ -582,6 +582,13 @@ uint8_t migrate_throttle_trigger_threshold(void) return s->parameters.throttle_trigger_threshold; } +const char *migrate_tls_creds(void) +{ + MigrationState *s = migrate_get_current(); + + return s->parameters.tls_creds; +} + uint64_t migrate_xbzrle_cache_size(void) { MigrationState *s = migrate_get_current(); diff --git a/migration/options.h b/migration/options.h index 3948218dbe..4603ac9201 100644 --- a/migration/options.h +++ b/migration/options.h @@ -80,6 +80,7 @@ MultiFDCompression migrate_multifd_compression(void); int migrate_multifd_zlib_level(void); int migrate_multifd_zstd_level(void); uint8_t migrate_throttle_trigger_threshold(void); +const char *migrate_tls_creds(void); uint64_t migrate_xbzrle_cache_size(void); /* parameters setters */ diff --git a/migration/tls.c b/migration/tls.c index acd38e0b62..6e70887699 100644 --- a/migration/tls.c +++ b/migration/tls.c @@ -34,20 +34,19 @@ migration_tls_get_creds(MigrationState *s, Error **errp) { Object *creds; + const char *tls_creds = migrate_tls_creds(); QCryptoTLSCreds *ret; - creds = object_resolve_path_component( - object_get_objects_root(), s->parameters.tls_creds); + creds = object_resolve_path_component(object_get_objects_root(), tls_creds); if (!creds) { - error_setg(errp, "No TLS credentials with id '%s'", - s->parameters.tls_creds); + error_setg(errp, "No TLS credentials with id '%s'", tls_creds); return NULL; } ret = (QCryptoTLSCreds *)object_dynamic_cast( creds, TYPE_QCRYPTO_TLS_CREDS); if (!ret) { error_setg(errp, "Object with id '%s' is not TLS credentials", - s->parameters.tls_creds); + tls_creds); return NULL; } if (!qcrypto_tls_creds_check_endpoint(ret, endpoint, errp)) { From 2eb0308bbd5e20bb20229c790dc2c7f1ae8e3ba9 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Thu, 2 Mar 2023 12:33:50 +0100 Subject: [PATCH 09/18] migration: Create migrate_tls_authz() function Signed-off-by: Juan Quintela Reviewed-by: Vladimir Sementsov-Ogievskiy --- Moved the type to const char * (vladimir) --- migration/options.c | 7 +++++++ migration/options.h | 1 + migration/tls.c | 5 +---- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/migration/options.c b/migration/options.c index b5d4ebef8d..014aecc9ee 100644 --- a/migration/options.c +++ b/migration/options.c @@ -582,6 +582,13 @@ uint8_t migrate_throttle_trigger_threshold(void) return s->parameters.throttle_trigger_threshold; } +const char *migrate_tls_authz(void) +{ + MigrationState *s = migrate_get_current(); + + return s->parameters.tls_authz; +} + const char *migrate_tls_creds(void) { MigrationState *s = migrate_get_current(); diff --git a/migration/options.h b/migration/options.h index 4603ac9201..987e639a49 100644 --- a/migration/options.h +++ b/migration/options.h @@ -80,6 +80,7 @@ MultiFDCompression migrate_multifd_compression(void); int migrate_multifd_zlib_level(void); int migrate_multifd_zstd_level(void); uint8_t migrate_throttle_trigger_threshold(void); +const char *migrate_tls_authz(void); const char *migrate_tls_creds(void); uint64_t migrate_xbzrle_cache_size(void); diff --git a/migration/tls.c b/migration/tls.c index 6e70887699..184db4d7bf 100644 --- a/migration/tls.c +++ b/migration/tls.c @@ -86,10 +86,7 @@ void migration_tls_channel_process_incoming(MigrationState *s, return; } - tioc = qio_channel_tls_new_server( - ioc, creds, - s->parameters.tls_authz, - errp); + tioc = qio_channel_tls_new_server(ioc, creds, migrate_tls_authz(), errp); if (!tioc) { return; } From 1f2f366c328e851f302c3a97ce4ac18f86a64279 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Thu, 2 Mar 2023 12:37:21 +0100 Subject: [PATCH 10/18] migration: Create migrate_tls_hostname() function Signed-off-by: Juan Quintela Reviewed-by: Vladimir Sementsov-Ogievskiy --- Moved the type to const char * (vladimir) --- migration/options.c | 7 +++++++ migration/options.h | 1 + migration/tls.c | 5 +++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/migration/options.c b/migration/options.c index 014aecc9ee..1aa9575bc0 100644 --- a/migration/options.c +++ b/migration/options.c @@ -596,6 +596,13 @@ const char *migrate_tls_creds(void) return s->parameters.tls_creds; } +const char *migrate_tls_hostname(void) +{ + MigrationState *s = migrate_get_current(); + + return s->parameters.tls_hostname; +} + uint64_t migrate_xbzrle_cache_size(void) { MigrationState *s = migrate_get_current(); diff --git a/migration/options.h b/migration/options.h index 987e639a49..819c1b1ce3 100644 --- a/migration/options.h +++ b/migration/options.h @@ -82,6 +82,7 @@ int migrate_multifd_zstd_level(void); uint8_t migrate_throttle_trigger_threshold(void); const char *migrate_tls_authz(void); const char *migrate_tls_creds(void); +const char *migrate_tls_hostname(void); uint64_t migrate_xbzrle_cache_size(void); /* parameters setters */ diff --git a/migration/tls.c b/migration/tls.c index 184db4d7bf..cd29177957 100644 --- a/migration/tls.c +++ b/migration/tls.c @@ -130,8 +130,9 @@ QIOChannelTLS *migration_tls_client_create(MigrationState *s, return NULL; } - if (s->parameters.tls_hostname && *s->parameters.tls_hostname) { - hostname = s->parameters.tls_hostname; + const char *tls_hostname = migrate_tls_hostname(); + if (tls_hostname && *tls_hostname) { + hostname = tls_hostname; } return qio_channel_tls_new_client(ioc, creds, hostname, errp); From b804b35b1c8a0edfd127ac20819c234be55ac7fc Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Thu, 2 Mar 2023 12:49:16 +0100 Subject: [PATCH 11/18] migration: Create migrate_block_bitmap_mapping() function Notice that we changed the test of ->has_block_bitmap_mapping for the test that block_bitmap_mapping is not NULL. Signed-off-by: Juan Quintela Reviewed-by: Vladimir Sementsov-Ogievskiy --- Make it return const (vladimir) --- migration/block-dirty-bitmap.c | 14 ++++++++------ migration/options.c | 7 +++++++ migration/options.h | 1 + 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c index a6ffae0002..6624f39bc6 100644 --- a/migration/block-dirty-bitmap.c +++ b/migration/block-dirty-bitmap.c @@ -605,11 +605,12 @@ static int init_dirty_bitmap_migration(DBMSaveState *s) SaveBitmapState *dbms; GHashTable *handled_by_blk = g_hash_table_new(NULL, NULL); BlockBackend *blk; - const MigrationParameters *mig_params = &migrate_get_current()->parameters; GHashTable *alias_map = NULL; + const BitmapMigrationNodeAliasList *block_bitmap_mapping = + migrate_block_bitmap_mapping(); - if (mig_params->has_block_bitmap_mapping) { - alias_map = construct_alias_map(mig_params->block_bitmap_mapping, true, + if (block_bitmap_mapping) { + alias_map = construct_alias_map(block_bitmap_mapping, true, &error_abort); } @@ -1158,7 +1159,8 @@ static int dirty_bitmap_load_header(QEMUFile *f, DBMLoadState *s, static int dirty_bitmap_load(QEMUFile *f, void *opaque, int version_id) { GHashTable *alias_map = NULL; - const MigrationParameters *mig_params = &migrate_get_current()->parameters; + const BitmapMigrationNodeAliasList *block_bitmap_mapping = + migrate_block_bitmap_mapping(); DBMLoadState *s = &((DBMState *)opaque)->load; int ret = 0; @@ -1170,8 +1172,8 @@ static int dirty_bitmap_load(QEMUFile *f, void *opaque, int version_id) return -EINVAL; } - if (mig_params->has_block_bitmap_mapping) { - alias_map = construct_alias_map(mig_params->block_bitmap_mapping, + if (block_bitmap_mapping) { + alias_map = construct_alias_map(block_bitmap_mapping, false, &error_abort); } diff --git a/migration/options.c b/migration/options.c index 1aa9575bc0..1840a3b220 100644 --- a/migration/options.c +++ b/migration/options.c @@ -455,6 +455,13 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, /* parameters */ +const BitmapMigrationNodeAliasList *migrate_block_bitmap_mapping(void) +{ + MigrationState *s = migrate_get_current(); + + return s->parameters.block_bitmap_mapping; +} + bool migrate_block_incremental(void) { MigrationState *s = migrate_get_current(); diff --git a/migration/options.h b/migration/options.h index 819c1b1ce3..9bcb9e558c 100644 --- a/migration/options.h +++ b/migration/options.h @@ -62,6 +62,7 @@ bool migrate_cap_set(int cap, bool value, Error **errp); /* parameters */ +const BitmapMigrationNodeAliasList *migrate_block_bitmap_mapping(void); bool migrate_block_incremental(void); uint32_t migrate_checkpoint_delay(void); int migrate_compress_level(void); From f9436522c8dd35a51f6d796501de7fd4d4928481 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Thu, 2 Mar 2023 12:55:57 +0100 Subject: [PATCH 12/18] migration: Move migration_properties to options.c Signed-off-by: Juan Quintela Reviewed-by: Vladimir Sementsov-Ogievskiy --- migration/migration.c | 157 ------------------------------------------ migration/options.c | 155 +++++++++++++++++++++++++++++++++++++++++ migration/options.h | 7 ++ 3 files changed, 162 insertions(+), 157 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index ef8caa79b9..3adcdfe286 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -52,8 +52,6 @@ #include "io/channel-tls.h" #include "migration/colo.h" #include "hw/boards.h" -#include "hw/qdev-properties.h" -#include "hw/qdev-properties-system.h" #include "monitor/monitor.h" #include "net/announce.h" #include "qemu/queue.h" @@ -65,51 +63,6 @@ #include "sysemu/qtest.h" #include "options.h" -#define MAX_THROTTLE (128 << 20) /* Migration transfer speed throttling */ - -/* Time in milliseconds we are allowed to stop the source, - * for sending the last part */ -#define DEFAULT_MIGRATE_SET_DOWNTIME 300 - -/* Default compression thread count */ -#define DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT 8 -/* Default decompression thread count, usually decompression is at - * least 4 times as fast as compression.*/ -#define DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT 2 -/*0: means nocompress, 1: best speed, ... 9: best compress ratio */ -#define DEFAULT_MIGRATE_COMPRESS_LEVEL 1 -/* Define default autoconverge cpu throttle migration parameters */ -#define DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD 50 -#define DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL 20 -#define DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT 10 -#define DEFAULT_MIGRATE_MAX_CPU_THROTTLE 99 - -/* Migration XBZRLE default cache size */ -#define DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE (64 * 1024 * 1024) - -/* The delay time (in ms) between two COLO checkpoints */ -#define DEFAULT_MIGRATE_X_CHECKPOINT_DELAY (200 * 100) -#define DEFAULT_MIGRATE_MULTIFD_CHANNELS 2 -#define DEFAULT_MIGRATE_MULTIFD_COMPRESSION MULTIFD_COMPRESSION_NONE -/* 0: means nocompress, 1: best speed, ... 9: best compress ratio */ -#define DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL 1 -/* 0: means nocompress, 1: best speed, ... 20: best compress ratio */ -#define DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL 1 - -/* Background transfer rate for postcopy, 0 means unlimited, note - * that page requests can still exceed this limit. - */ -#define DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH 0 - -/* - * Parameters for self_announce_delay giving a stream of RARP/ARP - * packets after migration. - */ -#define DEFAULT_MIGRATE_ANNOUNCE_INITIAL 50 -#define DEFAULT_MIGRATE_ANNOUNCE_MAX 550 -#define DEFAULT_MIGRATE_ANNOUNCE_ROUNDS 5 -#define DEFAULT_MIGRATE_ANNOUNCE_STEP 100 - static NotifierList migration_state_notifiers = NOTIFIER_LIST_INITIALIZER(migration_state_notifiers); @@ -3317,116 +3270,6 @@ void migrate_fd_connect(MigrationState *s, Error *error_in) s->migration_thread_running = true; } -#define DEFINE_PROP_MIG_CAP(name, x) \ - DEFINE_PROP_BOOL(name, MigrationState, capabilities[x], false) - -static Property migration_properties[] = { - DEFINE_PROP_BOOL("store-global-state", MigrationState, - store_global_state, true), - DEFINE_PROP_BOOL("send-configuration", MigrationState, - send_configuration, true), - DEFINE_PROP_BOOL("send-section-footer", MigrationState, - send_section_footer, true), - DEFINE_PROP_BOOL("decompress-error-check", MigrationState, - decompress_error_check, true), - DEFINE_PROP_UINT8("x-clear-bitmap-shift", MigrationState, - clear_bitmap_shift, CLEAR_BITMAP_SHIFT_DEFAULT), - DEFINE_PROP_BOOL("x-preempt-pre-7-2", MigrationState, - preempt_pre_7_2, false), - - /* Migration parameters */ - DEFINE_PROP_UINT8("x-compress-level", MigrationState, - parameters.compress_level, - DEFAULT_MIGRATE_COMPRESS_LEVEL), - DEFINE_PROP_UINT8("x-compress-threads", MigrationState, - parameters.compress_threads, - DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT), - DEFINE_PROP_BOOL("x-compress-wait-thread", MigrationState, - parameters.compress_wait_thread, true), - DEFINE_PROP_UINT8("x-decompress-threads", MigrationState, - parameters.decompress_threads, - DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT), - DEFINE_PROP_UINT8("x-throttle-trigger-threshold", MigrationState, - parameters.throttle_trigger_threshold, - DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD), - DEFINE_PROP_UINT8("x-cpu-throttle-initial", MigrationState, - parameters.cpu_throttle_initial, - DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL), - DEFINE_PROP_UINT8("x-cpu-throttle-increment", MigrationState, - parameters.cpu_throttle_increment, - DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT), - DEFINE_PROP_BOOL("x-cpu-throttle-tailslow", MigrationState, - parameters.cpu_throttle_tailslow, false), - DEFINE_PROP_SIZE("x-max-bandwidth", MigrationState, - parameters.max_bandwidth, MAX_THROTTLE), - DEFINE_PROP_UINT64("x-downtime-limit", MigrationState, - parameters.downtime_limit, - DEFAULT_MIGRATE_SET_DOWNTIME), - DEFINE_PROP_UINT32("x-checkpoint-delay", MigrationState, - parameters.x_checkpoint_delay, - DEFAULT_MIGRATE_X_CHECKPOINT_DELAY), - DEFINE_PROP_UINT8("multifd-channels", MigrationState, - parameters.multifd_channels, - DEFAULT_MIGRATE_MULTIFD_CHANNELS), - DEFINE_PROP_MULTIFD_COMPRESSION("multifd-compression", MigrationState, - parameters.multifd_compression, - DEFAULT_MIGRATE_MULTIFD_COMPRESSION), - DEFINE_PROP_UINT8("multifd-zlib-level", MigrationState, - parameters.multifd_zlib_level, - DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL), - DEFINE_PROP_UINT8("multifd-zstd-level", MigrationState, - parameters.multifd_zstd_level, - DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL), - DEFINE_PROP_SIZE("xbzrle-cache-size", MigrationState, - parameters.xbzrle_cache_size, - DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE), - DEFINE_PROP_SIZE("max-postcopy-bandwidth", MigrationState, - parameters.max_postcopy_bandwidth, - DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH), - DEFINE_PROP_UINT8("max-cpu-throttle", MigrationState, - parameters.max_cpu_throttle, - DEFAULT_MIGRATE_MAX_CPU_THROTTLE), - DEFINE_PROP_SIZE("announce-initial", MigrationState, - parameters.announce_initial, - DEFAULT_MIGRATE_ANNOUNCE_INITIAL), - DEFINE_PROP_SIZE("announce-max", MigrationState, - parameters.announce_max, - DEFAULT_MIGRATE_ANNOUNCE_MAX), - DEFINE_PROP_SIZE("announce-rounds", MigrationState, - parameters.announce_rounds, - DEFAULT_MIGRATE_ANNOUNCE_ROUNDS), - DEFINE_PROP_SIZE("announce-step", MigrationState, - parameters.announce_step, - DEFAULT_MIGRATE_ANNOUNCE_STEP), - DEFINE_PROP_STRING("tls-creds", MigrationState, parameters.tls_creds), - DEFINE_PROP_STRING("tls-hostname", MigrationState, parameters.tls_hostname), - DEFINE_PROP_STRING("tls-authz", MigrationState, parameters.tls_authz), - - /* Migration capabilities */ - DEFINE_PROP_MIG_CAP("x-xbzrle", MIGRATION_CAPABILITY_XBZRLE), - DEFINE_PROP_MIG_CAP("x-rdma-pin-all", MIGRATION_CAPABILITY_RDMA_PIN_ALL), - DEFINE_PROP_MIG_CAP("x-auto-converge", MIGRATION_CAPABILITY_AUTO_CONVERGE), - DEFINE_PROP_MIG_CAP("x-zero-blocks", MIGRATION_CAPABILITY_ZERO_BLOCKS), - DEFINE_PROP_MIG_CAP("x-compress", MIGRATION_CAPABILITY_COMPRESS), - DEFINE_PROP_MIG_CAP("x-events", MIGRATION_CAPABILITY_EVENTS), - DEFINE_PROP_MIG_CAP("x-postcopy-ram", MIGRATION_CAPABILITY_POSTCOPY_RAM), - DEFINE_PROP_MIG_CAP("x-postcopy-preempt", - MIGRATION_CAPABILITY_POSTCOPY_PREEMPT), - DEFINE_PROP_MIG_CAP("x-colo", MIGRATION_CAPABILITY_X_COLO), - DEFINE_PROP_MIG_CAP("x-release-ram", MIGRATION_CAPABILITY_RELEASE_RAM), - DEFINE_PROP_MIG_CAP("x-block", MIGRATION_CAPABILITY_BLOCK), - DEFINE_PROP_MIG_CAP("x-return-path", MIGRATION_CAPABILITY_RETURN_PATH), - DEFINE_PROP_MIG_CAP("x-multifd", MIGRATION_CAPABILITY_MULTIFD), - DEFINE_PROP_MIG_CAP("x-background-snapshot", - MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT), -#ifdef CONFIG_LINUX - DEFINE_PROP_MIG_CAP("x-zero-copy-send", - MIGRATION_CAPABILITY_ZERO_COPY_SEND), -#endif - - DEFINE_PROP_END_OF_LIST(), -}; - static void migration_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/migration/options.c b/migration/options.c index 1840a3b220..f2a77cdef1 100644 --- a/migration/options.c +++ b/migration/options.c @@ -31,6 +31,161 @@ #define MAX_MIGRATE_DOWNTIME_SECONDS 2000 #define MAX_MIGRATE_DOWNTIME (MAX_MIGRATE_DOWNTIME_SECONDS * 1000) +#define MAX_THROTTLE (128 << 20) /* Migration transfer speed throttling */ + +/* Time in milliseconds we are allowed to stop the source, + * for sending the last part */ +#define DEFAULT_MIGRATE_SET_DOWNTIME 300 + +/* Default compression thread count */ +#define DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT 8 +/* Default decompression thread count, usually decompression is at + * least 4 times as fast as compression.*/ +#define DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT 2 +/*0: means nocompress, 1: best speed, ... 9: best compress ratio */ +#define DEFAULT_MIGRATE_COMPRESS_LEVEL 1 +/* Define default autoconverge cpu throttle migration parameters */ +#define DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD 50 +#define DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL 20 +#define DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT 10 +#define DEFAULT_MIGRATE_MAX_CPU_THROTTLE 99 + +/* Migration XBZRLE default cache size */ +#define DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE (64 * 1024 * 1024) + +/* The delay time (in ms) between two COLO checkpoints */ +#define DEFAULT_MIGRATE_X_CHECKPOINT_DELAY (200 * 100) +#define DEFAULT_MIGRATE_MULTIFD_CHANNELS 2 +#define DEFAULT_MIGRATE_MULTIFD_COMPRESSION MULTIFD_COMPRESSION_NONE +/* 0: means nocompress, 1: best speed, ... 9: best compress ratio */ +#define DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL 1 +/* 0: means nocompress, 1: best speed, ... 20: best compress ratio */ +#define DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL 1 + +/* Background transfer rate for postcopy, 0 means unlimited, note + * that page requests can still exceed this limit. + */ +#define DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH 0 + +/* + * Parameters for self_announce_delay giving a stream of RARP/ARP + * packets after migration. + */ +#define DEFAULT_MIGRATE_ANNOUNCE_INITIAL 50 +#define DEFAULT_MIGRATE_ANNOUNCE_MAX 550 +#define DEFAULT_MIGRATE_ANNOUNCE_ROUNDS 5 +#define DEFAULT_MIGRATE_ANNOUNCE_STEP 100 + +#define DEFINE_PROP_MIG_CAP(name, x) \ + DEFINE_PROP_BOOL(name, MigrationState, capabilities[x], false) + +Property migration_properties[] = { + DEFINE_PROP_BOOL("store-global-state", MigrationState, + store_global_state, true), + DEFINE_PROP_BOOL("send-configuration", MigrationState, + send_configuration, true), + DEFINE_PROP_BOOL("send-section-footer", MigrationState, + send_section_footer, true), + DEFINE_PROP_BOOL("decompress-error-check", MigrationState, + decompress_error_check, true), + DEFINE_PROP_UINT8("x-clear-bitmap-shift", MigrationState, + clear_bitmap_shift, CLEAR_BITMAP_SHIFT_DEFAULT), + DEFINE_PROP_BOOL("x-preempt-pre-7-2", MigrationState, + preempt_pre_7_2, false), + + /* Migration parameters */ + DEFINE_PROP_UINT8("x-compress-level", MigrationState, + parameters.compress_level, + DEFAULT_MIGRATE_COMPRESS_LEVEL), + DEFINE_PROP_UINT8("x-compress-threads", MigrationState, + parameters.compress_threads, + DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT), + DEFINE_PROP_BOOL("x-compress-wait-thread", MigrationState, + parameters.compress_wait_thread, true), + DEFINE_PROP_UINT8("x-decompress-threads", MigrationState, + parameters.decompress_threads, + DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT), + DEFINE_PROP_UINT8("x-throttle-trigger-threshold", MigrationState, + parameters.throttle_trigger_threshold, + DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD), + DEFINE_PROP_UINT8("x-cpu-throttle-initial", MigrationState, + parameters.cpu_throttle_initial, + DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL), + DEFINE_PROP_UINT8("x-cpu-throttle-increment", MigrationState, + parameters.cpu_throttle_increment, + DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT), + DEFINE_PROP_BOOL("x-cpu-throttle-tailslow", MigrationState, + parameters.cpu_throttle_tailslow, false), + DEFINE_PROP_SIZE("x-max-bandwidth", MigrationState, + parameters.max_bandwidth, MAX_THROTTLE), + DEFINE_PROP_UINT64("x-downtime-limit", MigrationState, + parameters.downtime_limit, + DEFAULT_MIGRATE_SET_DOWNTIME), + DEFINE_PROP_UINT32("x-checkpoint-delay", MigrationState, + parameters.x_checkpoint_delay, + DEFAULT_MIGRATE_X_CHECKPOINT_DELAY), + DEFINE_PROP_UINT8("multifd-channels", MigrationState, + parameters.multifd_channels, + DEFAULT_MIGRATE_MULTIFD_CHANNELS), + DEFINE_PROP_MULTIFD_COMPRESSION("multifd-compression", MigrationState, + parameters.multifd_compression, + DEFAULT_MIGRATE_MULTIFD_COMPRESSION), + DEFINE_PROP_UINT8("multifd-zlib-level", MigrationState, + parameters.multifd_zlib_level, + DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL), + DEFINE_PROP_UINT8("multifd-zstd-level", MigrationState, + parameters.multifd_zstd_level, + DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL), + DEFINE_PROP_SIZE("xbzrle-cache-size", MigrationState, + parameters.xbzrle_cache_size, + DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE), + DEFINE_PROP_SIZE("max-postcopy-bandwidth", MigrationState, + parameters.max_postcopy_bandwidth, + DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH), + DEFINE_PROP_UINT8("max-cpu-throttle", MigrationState, + parameters.max_cpu_throttle, + DEFAULT_MIGRATE_MAX_CPU_THROTTLE), + DEFINE_PROP_SIZE("announce-initial", MigrationState, + parameters.announce_initial, + DEFAULT_MIGRATE_ANNOUNCE_INITIAL), + DEFINE_PROP_SIZE("announce-max", MigrationState, + parameters.announce_max, + DEFAULT_MIGRATE_ANNOUNCE_MAX), + DEFINE_PROP_SIZE("announce-rounds", MigrationState, + parameters.announce_rounds, + DEFAULT_MIGRATE_ANNOUNCE_ROUNDS), + DEFINE_PROP_SIZE("announce-step", MigrationState, + parameters.announce_step, + DEFAULT_MIGRATE_ANNOUNCE_STEP), + DEFINE_PROP_STRING("tls-creds", MigrationState, parameters.tls_creds), + DEFINE_PROP_STRING("tls-hostname", MigrationState, parameters.tls_hostname), + DEFINE_PROP_STRING("tls-authz", MigrationState, parameters.tls_authz), + + /* Migration capabilities */ + DEFINE_PROP_MIG_CAP("x-xbzrle", MIGRATION_CAPABILITY_XBZRLE), + DEFINE_PROP_MIG_CAP("x-rdma-pin-all", MIGRATION_CAPABILITY_RDMA_PIN_ALL), + DEFINE_PROP_MIG_CAP("x-auto-converge", MIGRATION_CAPABILITY_AUTO_CONVERGE), + DEFINE_PROP_MIG_CAP("x-zero-blocks", MIGRATION_CAPABILITY_ZERO_BLOCKS), + DEFINE_PROP_MIG_CAP("x-compress", MIGRATION_CAPABILITY_COMPRESS), + DEFINE_PROP_MIG_CAP("x-events", MIGRATION_CAPABILITY_EVENTS), + DEFINE_PROP_MIG_CAP("x-postcopy-ram", MIGRATION_CAPABILITY_POSTCOPY_RAM), + DEFINE_PROP_MIG_CAP("x-postcopy-preempt", + MIGRATION_CAPABILITY_POSTCOPY_PREEMPT), + DEFINE_PROP_MIG_CAP("x-colo", MIGRATION_CAPABILITY_X_COLO), + DEFINE_PROP_MIG_CAP("x-release-ram", MIGRATION_CAPABILITY_RELEASE_RAM), + DEFINE_PROP_MIG_CAP("x-block", MIGRATION_CAPABILITY_BLOCK), + DEFINE_PROP_MIG_CAP("x-return-path", MIGRATION_CAPABILITY_RETURN_PATH), + DEFINE_PROP_MIG_CAP("x-multifd", MIGRATION_CAPABILITY_MULTIFD), + DEFINE_PROP_MIG_CAP("x-background-snapshot", + MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT), +#ifdef CONFIG_LINUX + DEFINE_PROP_MIG_CAP("x-zero-copy-send", + MIGRATION_CAPABILITY_ZERO_COPY_SEND), +#endif + + DEFINE_PROP_END_OF_LIST(), +}; + bool migrate_auto_converge(void) { MigrationState *s = migrate_get_current(); diff --git a/migration/options.h b/migration/options.h index 9bcb9e558c..00854d60f9 100644 --- a/migration/options.h +++ b/migration/options.h @@ -14,6 +14,9 @@ #ifndef QEMU_MIGRATION_OPTIONS_H #define QEMU_MIGRATION_OPTIONS_H +#include "hw/qdev-properties.h" +#include "hw/qdev-properties-system.h" + /* constants */ /* Amount of time to allocate to each "chunk" of bandwidth-throttled @@ -21,6 +24,10 @@ #define BUFFER_DELAY 100 #define XFER_LIMIT_RATIO (1000 / BUFFER_DELAY) +/* migration properties */ + +extern Property migration_properties[]; + /* capabilities */ bool migrate_auto_converge(void); From 77c259a4cb1c9799754b48f570301ebf1de5ded8 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Tue, 21 Jun 2022 12:13:14 +0200 Subject: [PATCH 13/18] multifd: Create property multifd-flush-after-each-section 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 Reviewed-by: Dr. David Alan Gilbert Acked-by: Peter Xu --- Rename each-iteration to after-each-section Rename multifd-sync-after-each-section to multifd-flush-after-each-section Move to machine-8.0 (peter) --- hw/core/machine.c | 4 +++- migration/migration.h | 12 ++++++++++++ migration/options.c | 13 +++++++++++++ migration/options.h | 1 + 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/hw/core/machine.c b/hw/core/machine.c index 2ce97a5d3b..47a34841a5 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -39,7 +39,9 @@ #include "hw/virtio/virtio.h" #include "hw/virtio/virtio-pci.h" -GlobalProperty hw_compat_8_0[] = {}; +GlobalProperty hw_compat_8_0[] = { + { "migration", "multifd-flush-after-each-section", "on"}, +}; const size_t hw_compat_8_0_len = G_N_ELEMENTS(hw_compat_8_0); GlobalProperty hw_compat_7_2[] = { diff --git a/migration/migration.h b/migration/migration.h index 2b71df8617..e2247d708f 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 diff --git a/migration/options.c b/migration/options.c index f2a77cdef1..690c8f718e 100644 --- a/migration/options.c +++ b/migration/options.c @@ -88,6 +88,8 @@ 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, @@ -335,6 +337,17 @@ bool migrate_zero_copy_send(void) /* pseudo capabilities */ +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_postcopy(void) { return migrate_postcopy_ram() || migrate_dirty_bitmaps(); diff --git a/migration/options.h b/migration/options.h index 00854d60f9..3c322867cd 100644 --- a/migration/options.h +++ b/migration/options.h @@ -59,6 +59,7 @@ bool migrate_zero_copy_send(void); * check, but they are not a capability. */ +bool migrate_multifd_flush_after_each_section(void); bool migrate_postcopy(void); bool migrate_tls(void); From b05292c237030343516d073b1a1e5f49ffc017a8 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Tue, 21 Jun 2022 12:21:32 +0200 Subject: [PATCH 14/18] multifd: Protect multifd_send_sync_main() calls 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 Reviewed-by: Dr. David Alan Gilbert Acked-by: Peter Xu --- 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 01356f60a4..1e2414d681 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -3394,9 +3394,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); @@ -4153,7 +4155,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" @@ -4424,7 +4428,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) { From 294e5a4034e81b3d8db03b4e0f691386f20d6ed3 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Tue, 21 Jun 2022 13:36:11 +0200 Subject: [PATCH 15/18] multifd: Only flush once each full round of memory 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 Acked-by: Peter Xu --- Add missing qemu_fflush(), now it passes all tests always. In the previous version, the check that changes the default value to false got lost in some rebase. Get it back. --- migration/migration.h | 3 +-- migration/options.c | 8 ++------ migration/ram.c | 28 +++++++++++++++++++++++++++- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/migration/migration.h b/migration/migration.h index e2247d708f..3a918514e7 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/options.c b/migration/options.c index 690c8f718e..53b7fc5d5d 100644 --- a/migration/options.c +++ b/migration/options.c @@ -89,7 +89,7 @@ Property migration_properties[] = { 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), + multifd_flush_after_each_section, false), DEFINE_PROP_UINT8("x-clear-bitmap-shift", MigrationState, clear_bitmap_shift, CLEAR_BITMAP_SHIFT_DEFAULT), DEFINE_PROP_BOOL("x-preempt-pre-7-2", MigrationState, @@ -341,11 +341,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_postcopy(void) diff --git a/migration/ram.c b/migration/ram.c index 1e2414d681..e9dcda8b9d 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -86,6 +86,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, @@ -1581,6 +1582,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 @@ -1608,6 +1610,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 @@ -2600,6 +2611,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; } } } @@ -3286,6 +3300,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); @@ -3471,6 +3489,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); @@ -4152,7 +4173,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()) { @@ -4426,6 +4449,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()) { From 7757b55eedd5d571d0b0c5f570b01dc3ca910a62 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 27 Apr 2023 10:47:58 +0200 Subject: [PATCH 16/18] stat64: Add stat64_set() operation Signed-off-by: Paolo Bonzini Reviewed-by: Juan Quintela Reviewed-by: Richard Henderson Signed-off-by: Juan Quintela --- include/qemu/stats64.h | 6 ++++++ util/stats64.c | 11 +++++++++++ 2 files changed, 17 insertions(+) diff --git a/include/qemu/stats64.h b/include/qemu/stats64.h index 802402254b..99b5cb724a 100644 --- a/include/qemu/stats64.h +++ b/include/qemu/stats64.h @@ -40,6 +40,11 @@ static inline uint64_t stat64_get(const Stat64 *s) return qatomic_read__nocheck(&s->value); } +static inline void stat64_set(Stat64 *s, uint64_t value) +{ + qatomic_set__nocheck(&s->value, value); +} + static inline void stat64_add(Stat64 *s, uint64_t value) { qatomic_add(&s->value, value); @@ -62,6 +67,7 @@ static inline void stat64_max(Stat64 *s, uint64_t value) } #else uint64_t stat64_get(const Stat64 *s); +void stat64_set(Stat64 *s, uint64_t value); bool stat64_min_slow(Stat64 *s, uint64_t value); bool stat64_max_slow(Stat64 *s, uint64_t value); bool stat64_add32_carry(Stat64 *s, uint32_t low, uint32_t high); diff --git a/util/stats64.c b/util/stats64.c index 897613c949..09736014ec 100644 --- a/util/stats64.c +++ b/util/stats64.c @@ -57,6 +57,17 @@ uint64_t stat64_get(const Stat64 *s) return ((uint64_t)high << 32) | low; } +void stat64_set(Stat64 *s, uint64_t val) +{ + while (!stat64_wrtrylock(s)) { + cpu_relax(); + } + + qatomic_set(&s->high, val >> 32); + qatomic_set(&s->low, val); + stat64_wrunlock(s); +} + bool stat64_add32_carry(Stat64 *s, uint32_t low, uint32_t high) { uint32_t old; From 72f8e58707395d24c177ffa9f88a25329638fc98 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Tue, 11 Apr 2023 18:19:05 +0200 Subject: [PATCH 17/18] migration: Make dirty_pages_rate atomic Signed-off-by: Juan Quintela Reviewed-by: Richard Henderson Reviewed-by: Peter Xu --- Don't use __nocheck() variants Use stat64_get() --- migration/migration.c | 6 ++++-- migration/ram.c | 5 +++-- migration/ram.h | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index 3adcdfe286..9367bb2afc 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -958,7 +958,8 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s) if (s->state != MIGRATION_STATUS_COMPLETED) { info->ram->remaining = ram_bytes_remaining(); - info->ram->dirty_pages_rate = ram_counters.dirty_pages_rate; + info->ram->dirty_pages_rate = + stat64_get(&ram_counters.dirty_pages_rate); } } @@ -2689,7 +2690,8 @@ static void migration_update_counters(MigrationState *s, * if we haven't sent anything, we don't want to * recalculate. 10000 is a small enough number for our purposes */ - if (ram_counters.dirty_pages_rate && transferred > 10000) { + if (stat64_get(&ram_counters.dirty_pages_rate) && + transferred > 10000) { s->expected_downtime = ram_counters.remaining / bandwidth; } diff --git a/migration/ram.c b/migration/ram.c index e9dcda8b9d..5846f6e27f 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -1130,8 +1130,9 @@ static void migration_update_rates(RAMState *rs, int64_t end_time) double compressed_size; /* calculate period counters */ - ram_counters.dirty_pages_rate = rs->num_dirty_pages_period * 1000 - / (end_time - rs->time_last_bitmap_sync); + stat64_set(&ram_counters.dirty_pages_rate, + rs->num_dirty_pages_period * 1000 / + (end_time - rs->time_last_bitmap_sync)); if (!page_count) { return; diff --git a/migration/ram.h b/migration/ram.h index a6e0d70226..f189cc79f8 100644 --- a/migration/ram.h +++ b/migration/ram.h @@ -41,7 +41,7 @@ * one thread). */ typedef struct { - int64_t dirty_pages_rate; + Stat64 dirty_pages_rate; Stat64 dirty_sync_count; Stat64 dirty_sync_missed_zero_copy; Stat64 downtime_bytes; From 73208a336e249bc8e3bdd76a78d0af7ecaee9178 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Tue, 11 Apr 2023 18:31:20 +0200 Subject: [PATCH 18/18] migration: Make dirty_bytes_last_sync atomic As we set its value, it needs to be operated with atomics. We rename it from remaining to better reflect its meaning. Statistics always return the real reamaining bytes. This was used to store how much pages where dirty on the previous generation, so we can calculate the expected downtime as: dirty_bytes_last_sync / current_bandwith. If we use the actual remaining bytes, we would see a very small value at the end of the iteration. Signed-off-by: Juan Quintela Reviewed-by: Peter Xu Reviewed-by: Richard Henderson --- I am open to use ram_bytes_remaining() in its only use and be more "optimistic" about the downtime. Don't use __nocheck() functions. Use stat64_get() now that it exists. --- migration/migration.c | 3 ++- migration/ram.c | 2 +- migration/ram.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index 9367bb2afc..abcadbb619 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -2692,7 +2692,8 @@ static void migration_update_counters(MigrationState *s, */ if (stat64_get(&ram_counters.dirty_pages_rate) && transferred > 10000) { - s->expected_downtime = ram_counters.remaining / bandwidth; + s->expected_downtime = + stat64_get(&ram_counters.dirty_bytes_last_sync) / bandwidth; } qemu_file_reset_rate_limit(s->to_dst_file); diff --git a/migration/ram.c b/migration/ram.c index 5846f6e27f..89be3e3320 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -1224,7 +1224,7 @@ static void migration_bitmap_sync(RAMState *rs) RAMBLOCK_FOREACH_NOT_IGNORED(block) { ramblock_sync_dirty_bitmap(rs, block); } - ram_counters.remaining = ram_bytes_remaining(); + stat64_set(&ram_counters.dirty_bytes_last_sync, ram_bytes_remaining()); } qemu_mutex_unlock(&rs->bitmap_mutex); diff --git a/migration/ram.h b/migration/ram.h index f189cc79f8..04b05e1b2c 100644 --- a/migration/ram.h +++ b/migration/ram.h @@ -41,6 +41,7 @@ * one thread). */ typedef struct { + Stat64 dirty_bytes_last_sync; Stat64 dirty_pages_rate; Stat64 dirty_sync_count; Stat64 dirty_sync_missed_zero_copy; @@ -51,7 +52,6 @@ typedef struct { Stat64 postcopy_bytes; Stat64 postcopy_requests; Stat64 precopy_bytes; - int64_t remaining; Stat64 transferred; } RAMStats;