diff options
-rw-r--r-- | hw/core/machine.c | 4 | ||||
-rw-r--r-- | include/qemu/stats64.h | 6 | ||||
-rw-r--r-- | migration/block-dirty-bitmap.c | 14 | ||||
-rw-r--r-- | migration/migration.c | 220 | ||||
-rw-r--r-- | migration/migration.h | 11 | ||||
-rw-r--r-- | migration/multifd.c | 3 | ||||
-rw-r--r-- | migration/options.c | 404 | ||||
-rw-r--r-- | migration/options.h | 19 | ||||
-rw-r--r-- | migration/ram.c | 51 | ||||
-rw-r--r-- | migration/ram.h | 4 | ||||
-rw-r--r-- | migration/tls.c | 19 | ||||
-rw-r--r-- | util/stats64.c | 11 |
12 files changed, 414 insertions, 352 deletions
diff --git a/hw/core/machine.c b/hw/core/machine.c index 2ce97a5..47a3484 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/include/qemu/stats64.h b/include/qemu/stats64.h index 8024022..99b5cb7 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/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c index a6ffae0..6624f39 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/migration.c b/migration/migration.c index 22e8586..abcadbb 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); @@ -1005,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); } } @@ -1164,21 +1118,6 @@ 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); - s->must_remove_block_options = false; - } -} - static void migrate_fd_cleanup(MigrationState *s) { qemu_bh_delete(s->cleanup_bh); @@ -1233,7 +1172,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); } @@ -1668,7 +1607,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); @@ -1727,7 +1666,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; } @@ -2737,7 +2676,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; @@ -2751,8 +2690,10 @@ 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) { - s->expected_downtime = ram_counters.remaining / bandwidth; + if (stat64_get(&ram_counters.dirty_pages_rate) && + transferred > 10000) { + s->expected_downtime = + stat64_get(&ram_counters.dirty_bytes_last_sync) / bandwidth; } qemu_file_reset_rate_limit(s->to_dst_file); @@ -3244,7 +3185,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 { @@ -3332,116 +3273,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); @@ -3470,7 +3301,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 +3308,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/migration.h b/migration/migration.h index 2b71df8..3a91851 100644 --- a/migration/migration.h +++ b/migration/migration.h @@ -405,6 +405,17 @@ 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. (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 * be GUEST_PAGE_SIZE << N. Say, N=0 means we will clear dirty diff --git a/migration/multifd.c b/migration/multifd.c index cce3ad6..6a59c03 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; diff --git a/migration/options.c b/migration/options.c index c603058..53b7fc5 100644 --- a/migration/options.c +++ b/migration/options.c @@ -31,29 +31,180 @@ #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_BOOL("multifd-flush-after-each-section", MigrationState, + 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, + 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; - - 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 +212,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,60 +295,55 @@ 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]; } /* pseudo capabilities */ +bool migrate_multifd_flush_after_each_section(void) +{ + MigrationState *s = migrate_get_current(); + + return s->multifd_flush_after_each_section; +} + bool migrate_postcopy(void) { return migrate_postcopy_ram() || migrate_dirty_bitmaps(); @@ -224,9 +351,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; } @@ -494,128 +619,114 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, /* parameters */ -bool migrate_block_incremental(void) +const BitmapMigrationNodeAliasList *migrate_block_bitmap_mapping(void) { - MigrationState *s; + MigrationState *s = migrate_get_current(); - s = migrate_get_current(); + return s->parameters.block_bitmap_mapping; +} + +bool migrate_block_incremental(void) +{ + 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) +uint64_t migrate_downtime_limit(void) { - MigrationState *s; + MigrationState *s = migrate_get_current(); - s = migrate_get_current(); + return s->parameters.downtime_limit; +} + +uint8_t migrate_max_cpu_throttle(void) +{ + 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,42 +734,76 @@ 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) +const char *migrate_tls_authz(void) +{ + MigrationState *s = migrate_get_current(); + + return s->parameters.tls_authz; +} + +const char *migrate_tls_creds(void) { - MigrationState *s; + MigrationState *s = migrate_get_current(); - s = migrate_get_current(); + 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(); 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 */ +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); + migrate_set_block_incremental(false); + s->must_remove_block_options = false; + } +} + AnnounceParameters *migrate_announce_params(void) { static AnnounceParameters ap; @@ -741,6 +886,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 89067e5..3c32286 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); @@ -52,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); @@ -62,6 +70,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); @@ -71,6 +80,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); @@ -79,10 +89,19 @@ 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); +const char *migrate_tls_hostname(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); +void migrate_params_init(MigrationParameters *params); +void block_cleanup_parameters(void); #endif diff --git a/migration/ram.c b/migration/ram.c index 01356f6..89be3e3 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, @@ -1129,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; @@ -1222,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); @@ -1581,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 @@ -1608,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 @@ -2600,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; } } } @@ -3286,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); @@ -3394,9 +3413,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); @@ -3469,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); @@ -4150,10 +4174,14 @@ 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 */ - 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" @@ -4422,9 +4450,14 @@ 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 */ - multifd_recv_sync_main(); + if (migrate_multifd_flush_after_each_section()) { + multifd_recv_sync_main(); + } break; default: if (flags & RAM_SAVE_FLAG_HOOK) { diff --git a/migration/ram.h b/migration/ram.h index a6e0d70..04b05e1 100644 --- a/migration/ram.h +++ b/migration/ram.h @@ -41,7 +41,8 @@ * one thread). */ typedef struct { - int64_t dirty_pages_rate; + Stat64 dirty_bytes_last_sync; + Stat64 dirty_pages_rate; Stat64 dirty_sync_count; Stat64 dirty_sync_missed_zero_copy; Stat64 downtime_bytes; @@ -51,7 +52,6 @@ typedef struct { Stat64 postcopy_bytes; Stat64 postcopy_requests; Stat64 precopy_bytes; - int64_t remaining; Stat64 transferred; } RAMStats; diff --git a/migration/tls.c b/migration/tls.c index acd38e0..cd29177 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)) { @@ -87,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; } @@ -134,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); diff --git a/util/stats64.c b/util/stats64.c index 897613c..0973601 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; |