/*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
params->compress_wait_thread = s->parameters.compress_wait_thread;
params->has_decompress_threads = true;
params->decompress_threads = s->parameters.decompress_threads;
+ params->has_throttle_trigger_threshold = true;
+ params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold;
params->has_cpu_throttle_initial = true;
params->cpu_throttle_initial = s->parameters.cpu_throttle_initial;
params->has_cpu_throttle_increment = true;
params->cpu_throttle_increment = s->parameters.cpu_throttle_increment;
+ params->has_cpu_throttle_tailslow = true;
+ params->cpu_throttle_tailslow = s->parameters.cpu_throttle_tailslow;
params->has_tls_creds = true;
params->tls_creds = g_strdup(s->parameters.tls_creds);
params->has_tls_hostname = true;
params->tls_hostname = g_strdup(s->parameters.tls_hostname);
params->has_tls_authz = true;
- params->tls_authz = g_strdup(s->parameters.tls_authz);
+ params->tls_authz = g_strdup(s->parameters.tls_authz ?
+ s->parameters.tls_authz : "");
params->has_max_bandwidth = true;
params->max_bandwidth = s->parameters.max_bandwidth;
params->has_downtime_limit = true;
case MIGRATION_STATUS_PRE_SWITCHOVER:
case MIGRATION_STATUS_DEVICE:
case MIGRATION_STATUS_WAIT_UNPLUG:
+ case MIGRATION_STATUS_COLO:
return true;
default:
info->xbzrle_cache->pages = xbzrle_counters.pages;
info->xbzrle_cache->cache_miss = xbzrle_counters.cache_miss;
info->xbzrle_cache->cache_miss_rate = xbzrle_counters.cache_miss_rate;
+ info->xbzrle_cache->encoding_rate = xbzrle_counters.encoding_rate;
info->xbzrle_cache->overflow = xbzrle_counters.overflow;
}
return false;
}
+ if (params->has_throttle_trigger_threshold &&
+ (params->throttle_trigger_threshold < 1 ||
+ params->throttle_trigger_threshold > 100)) {
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
+ "throttle_trigger_threshold",
+ "an integer in the range of 1 to 100");
+ return false;
+ }
+
if (params->has_cpu_throttle_initial &&
(params->cpu_throttle_initial < 1 ||
params->cpu_throttle_initial > 99)) {
}
if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) {
- error_setg(errp, "Parameter 'max_bandwidth' expects an integer in the"
- " range of 0 to %zu bytes/second", SIZE_MAX);
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
+ "max_bandwidth",
+ "an integer in the range of 0 to "stringify(SIZE_MAX)
+ " bytes/second");
return false;
}
if (params->has_downtime_limit &&
(params->downtime_limit > MAX_MIGRATE_DOWNTIME)) {
- error_setg(errp, "Parameter 'downtime_limit' expects an integer in "
- "the range of 0 to %d milliseconds",
- MAX_MIGRATE_DOWNTIME);
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
+ "downtime_limit",
+ "an integer in the range of 0 to "
+ stringify(MAX_MIGRATE_DOWNTIME)" ms");
return false;
}
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
"xbzrle_cache_size",
"is invalid, it should be bigger than target page size"
- " and a power of two");
+ " and a power of 2");
return false;
}
dest->decompress_threads = params->decompress_threads;
}
+ if (params->has_throttle_trigger_threshold) {
+ dest->throttle_trigger_threshold = params->throttle_trigger_threshold;
+ }
+
if (params->has_cpu_throttle_initial) {
dest->cpu_throttle_initial = params->cpu_throttle_initial;
}
dest->cpu_throttle_increment = params->cpu_throttle_increment;
}
+ if (params->has_cpu_throttle_tailslow) {
+ dest->cpu_throttle_tailslow = params->cpu_throttle_tailslow;
+ }
+
if (params->has_tls_creds) {
assert(params->tls_creds->type == QTYPE_QSTRING);
dest->tls_creds = g_strdup(params->tls_creds->u.s);
s->parameters.decompress_threads = params->decompress_threads;
}
+ if (params->has_throttle_trigger_threshold) {
+ s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold;
+ }
+
if (params->has_cpu_throttle_initial) {
s->parameters.cpu_throttle_initial = params->cpu_throttle_initial;
}
s->parameters.cpu_throttle_increment = params->cpu_throttle_increment;
}
+ if (params->has_cpu_throttle_tailslow) {
+ s->parameters.cpu_throttle_tailslow = params->cpu_throttle_tailslow;
+ }
+
if (params->has_tls_creds) {
g_free(s->parameters.tls_creds);
assert(params->tls_creds->type == QTYPE_QSTRING);
void migrate_set_error(MigrationState *s, const Error *error)
{
- qemu_mutex_lock(&s->error_mutex);
+ QEMU_LOCK_GUARD(&s->error_mutex);
if (!s->error) {
s->error = error_copy(error);
}
- qemu_mutex_unlock(&s->error_mutex);
}
void migrate_fd_error(MigrationState *s, const Error *error)
void qmp_migrate_set_downtime(double value, Error **errp)
{
if (value < 0 || value > MAX_MIGRATE_DOWNTIME_SECONDS) {
- error_setg(errp, "Parameter 'downtime_limit' expects an integer in "
- "the range of 0 to %d seconds",
- MAX_MIGRATE_DOWNTIME_SECONDS);
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
+ "downtime_limit",
+ "an integer in the range of 0 to "
+ stringify(MAX_MIGRATE_DOWNTIME_SECONDS)" seconds");
return;
}
if (header_type >= MIG_RP_MSG_MAX ||
header_type == MIG_RP_MSG_INVALID) {
error_report("RP: Received invalid message 0x%04x length 0x%04x",
- header_type, header_len);
+ header_type, header_len);
mark_source_rp_bad(ms);
goto out;
}
header_len != rp_cmd_args[header_type].len) ||
header_len > sizeof(buf)) {
error_report("RP: Received '%s' message (0x%04x) with"
- "incorrect length %d expecting %zu",
- rp_cmd_args[header_type].name, header_type, header_len,
- (size_t)rp_cmd_args[header_type].len);
+ "incorrect length %d expecting %zu",
+ rp_cmd_args[header_type].name, header_type, header_len,
+ (size_t)rp_cmd_args[header_type].len);
mark_source_rp_bad(ms);
goto out;
}
}
if (header_len != expected_len) {
error_report("RP: Req_Page_id with length %d expecting %zd",
- header_len, expected_len);
+ header_len, expected_len);
mark_source_rp_bad(ms);
goto out;
}
bool resume = s->state == MIGRATION_STATUS_POSTCOPY_PAUSED;
s->expected_downtime = s->parameters.downtime_limit;
- s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup_bh, s);
+ if (resume) {
+ assert(s->cleanup_bh);
+ } else {
+ assert(!s->cleanup_bh);
+ s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup_bh, s);
+ }
if (error_in) {
migrate_fd_error(s, error_in);
migrate_fd_cleanup(s);
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,
params->has_compress_level = true;
params->has_compress_threads = 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;