monitor_printf(mon, "%s: %" PRIu64 "\n",
MigrationParameter_str(MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE),
params->xbzrle_cache_size);
+ monitor_printf(mon, "%s: %" PRIu64 "\n",
+ MigrationParameter_str(MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH),
+ params->max_postcopy_bandwidth);
}
qapi_free_MigrationParameters(params);
}
p->xbzrle_cache_size = cache_size;
break;
+ case MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH:
+ p->has_max_postcopy_bandwidth = true;
+ visit_type_size(v, param, &p->max_postcopy_bandwidth, &err);
+ break;
default:
assert(0);
}
#define DEFAULT_MIGRATE_MULTIFD_CHANNELS 2
#define DEFAULT_MIGRATE_MULTIFD_PAGE_COUNT 16
+/* Background transfer rate for postcopy, 0 means unlimited, note
+ * that page requests can still exceed this limit.
+ */
+#define DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH 0
+
static NotifierList migration_state_notifiers =
NOTIFIER_LIST_INITIALIZER(migration_state_notifiers);
params->x_multifd_page_count = s->parameters.x_multifd_page_count;
params->has_xbzrle_cache_size = true;
params->xbzrle_cache_size = s->parameters.xbzrle_cache_size;
+ params->has_max_postcopy_bandwidth = true;
+ params->max_postcopy_bandwidth = s->parameters.max_postcopy_bandwidth;
return params;
}
if (params->has_xbzrle_cache_size) {
dest->xbzrle_cache_size = params->xbzrle_cache_size;
}
+ if (params->has_max_postcopy_bandwidth) {
+ dest->max_postcopy_bandwidth = params->max_postcopy_bandwidth;
+ }
}
static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
s->parameters.xbzrle_cache_size = params->xbzrle_cache_size;
xbzrle_cache_resize(params->xbzrle_cache_size, errp);
}
+ if (params->has_max_postcopy_bandwidth) {
+ s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth;
+ }
}
void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp)
return s->parameters.xbzrle_cache_size;
}
+static int64_t migrate_max_postcopy_bandwidth(void)
+{
+ MigrationState *s;
+
+ s = migrate_get_current();
+
+ return s->parameters.max_postcopy_bandwidth;
+}
+
+
bool migrate_use_block(void)
{
MigrationState *s;
QIOChannelBuffer *bioc;
QEMUFile *fb;
int64_t time_at_stop = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+ int64_t bandwidth = migrate_max_postcopy_bandwidth();
bool restart_block = false;
int cur_state = MIGRATION_STATUS_ACTIVE;
if (!migrate_pause_before_switchover()) {
* will notice we're in POSTCOPY_ACTIVE and not actually
* wrap their state up here
*/
- qemu_file_set_rate_limit(ms->to_dst_file, INT64_MAX);
+ /* 0 max-postcopy-bandwidth means unlimited */
+ if (!bandwidth) {
+ qemu_file_set_rate_limit(ms->to_dst_file, INT64_MAX);
+ } else {
+ qemu_file_set_rate_limit(ms->to_dst_file, bandwidth / XFER_LIMIT_RATIO);
+ }
if (migrate_postcopy_ram()) {
/* Ping just for debugging, helps line traces up */
qemu_savevm_send_ping(ms->to_dst_file, 2);
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),
/* Migration capabilities */
DEFINE_PROP_MIG_CAP("x-xbzrle", MIGRATION_CAPABILITY_XBZRLE),
params->has_x_multifd_channels = true;
params->has_x_multifd_page_count = true;
params->has_xbzrle_cache_size = true;
+ params->has_max_postcopy_bandwidth = true;
qemu_sem_init(&ms->postcopy_pause_sem, 0);
qemu_sem_init(&ms->postcopy_pause_rp_sem, 0);
# and a power of 2
# (Since 2.11)
#
+# @max-postcopy-bandwidth: Background transfer bandwidth during postcopy.
+# Defaults to 0 (unlimited). In bytes per second.
+# (Since 3.0)
# Since: 2.4
##
{ 'enum': 'MigrationParameter',
'tls-creds', 'tls-hostname', 'max-bandwidth',
'downtime-limit', 'x-checkpoint-delay', 'block-incremental',
'x-multifd-channels', 'x-multifd-page-count',
- 'xbzrle-cache-size' ] }
+ 'xbzrle-cache-size', 'max-postcopy-bandwidth' ] }
##
# @MigrateSetParameters:
# needs to be a multiple of the target page size
# and a power of 2
# (Since 2.11)
+#
+# @max-postcopy-bandwidth: Background transfer bandwidth during postcopy.
+# Defaults to 0 (unlimited). In bytes per second.
+# (Since 3.0)
# Since: 2.4
##
# TODO either fuse back into MigrationParameters, or make
'*block-incremental': 'bool',
'*x-multifd-channels': 'int',
'*x-multifd-page-count': 'int',
- '*xbzrle-cache-size': 'size' } }
+ '*xbzrle-cache-size': 'size',
+ '*max-postcopy-bandwidth': 'size' } }
##
# @migrate-set-parameters:
# needs to be a multiple of the target page size
# and a power of 2
# (Since 2.11)
+#
+# @max-postcopy-bandwidth: Background transfer bandwidth during postcopy.
+# Defaults to 0 (unlimited). In bytes per second.
+# (Since 3.0)
# Since: 2.4
##
{ 'struct': 'MigrationParameters',
'*block-incremental': 'bool' ,
'*x-multifd-channels': 'uint8',
'*x-multifd-page-count': 'uint32',
- '*xbzrle-cache-size': 'size' } }
+ '*xbzrle-cache-size': 'size',
+ '*max-postcopy-bandwidth': 'size' } }
##
# @query-migrate-parameters: