@@ -670,6 +670,18 @@
{ 'enum': 'MigMode',
'data': [ 'normal', 'cpr-reboot' ] }
+##
+# @ZeroPageDetection:
+#
+# @none: Do not perform zero page checking.
+#
+# @legacy: Perform zero page checking in main migration thread.
+#
+# Since: 9.0
+##
+{ 'enum': 'ZeroPageDetection',
+ 'data': [ 'none', 'legacy' ] }
+
##
# @BitmapMigrationBitmapAliasTransform:
#
@@ -891,6 +903,10 @@
# @mode: Migration mode. See description in @MigMode. Default is 'normal'.
# (Since 8.2)
#
+# @zero-page-detection: Whether and how to detect zero pages.
+# See description in @ZeroPageDetection. Default is 'legacy'.
+# (since 9.0)
+#
# Features:
#
# @deprecated: Member @block-incremental is deprecated. Use
@@ -924,7 +940,8 @@
'block-bitmap-mapping',
{ 'name': 'x-vcpu-dirty-limit-period', 'features': ['unstable'] },
'vcpu-dirty-limit',
- 'mode'] }
+ 'mode',
+ 'zero-page-detection'] }
##
# @MigrateSetParameters:
@@ -1083,6 +1100,10 @@
# @mode: Migration mode. See description in @MigMode. Default is 'normal'.
# (Since 8.2)
#
+# @zero-page-detection: Whether and how to detect zero pages.
+# See description in @ZeroPageDetection. Default is 'legacy'.
+# (since 9.0)
+#
# Features:
#
# @deprecated: Member @block-incremental is deprecated. Use
@@ -1136,7 +1157,8 @@
'*x-vcpu-dirty-limit-period': { 'type': 'uint64',
'features': [ 'unstable' ] },
'*vcpu-dirty-limit': 'uint64',
- '*mode': 'MigMode'} }
+ '*mode': 'MigMode',
+ '*zero-page-detection': 'ZeroPageDetection'} }
##
# @migrate-set-parameters:
@@ -1311,6 +1333,10 @@
# @mode: Migration mode. See description in @MigMode. Default is 'normal'.
# (Since 8.2)
#
+# @zero-page-detection: Whether and how to detect zero pages.
+# See description in @ZeroPageDetection. Default is 'legacy'.
+# (since 9.0)
+#
# Features:
#
# @deprecated: Member @block-incremental is deprecated. Use
@@ -1361,7 +1387,8 @@
'*x-vcpu-dirty-limit-period': { 'type': 'uint64',
'features': [ 'unstable' ] },
'*vcpu-dirty-limit': 'uint64',
- '*mode': 'MigMode'} }
+ '*mode': 'MigMode',
+ '*zero-page-detection': 'ZeroPageDetection'} }
##
# @query-migrate-parameters:
@@ -9,6 +9,7 @@ extern const PropertyInfo qdev_prop_reserved_region;
extern const PropertyInfo qdev_prop_multifd_compression;
extern const PropertyInfo qdev_prop_mig_mode;
extern const PropertyInfo qdev_prop_granule_mode;
+extern const PropertyInfo qdev_prop_zero_page_detection;
extern const PropertyInfo qdev_prop_losttickpolicy;
extern const PropertyInfo qdev_prop_blockdev_on_error;
extern const PropertyInfo qdev_prop_bios_chs_trans;
@@ -50,6 +51,9 @@ extern const PropertyInfo qdev_prop_iothread_vq_mapping_list;
MigMode)
#define DEFINE_PROP_GRANULE_MODE(_n, _s, _f, _d) \
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_granule_mode, GranuleMode)
+#define DEFINE_PROP_ZERO_PAGE_DETECTION(_n, _s, _f, _d) \
+ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_zero_page_detection, \
+ ZeroPageDetection)
#define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
LostTickPolicy)
@@ -90,6 +90,7 @@ 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);
+ZeroPageDetection migrate_zero_page_detection(void);
/* parameters setters */
@@ -693,6 +693,16 @@ const PropertyInfo qdev_prop_granule_mode = {
.set_default_value = qdev_propinfo_set_default_value_enum,
};
+const PropertyInfo qdev_prop_zero_page_detection = {
+ .name = "ZeroPageDetection",
+ .description = "zero_page_detection values, "
+ "none,legacy",
+ .enum_table = &ZeroPageDetection_lookup,
+ .get = qdev_propinfo_get_enum,
+ .set = qdev_propinfo_set_enum,
+ .set_default_value = qdev_propinfo_set_default_value_enum,
+};
+
/* --- Reserved Region --- */
/*
@@ -344,6 +344,11 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
monitor_printf(mon, "%s: %s\n",
MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_COMPRESSION),
MultiFDCompression_str(params->multifd_compression));
+ assert(params->has_zero_page_detection);
+ monitor_printf(mon, "%s: %s\n",
+ MigrationParameter_str(MIGRATION_PARAMETER_ZERO_PAGE_DETECTION),
+ qapi_enum_lookup(&ZeroPageDetection_lookup,
+ params->zero_page_detection));
monitor_printf(mon, "%s: %" PRIu64 " bytes\n",
MigrationParameter_str(MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE),
params->xbzrle_cache_size);
@@ -634,6 +639,10 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
p->has_multifd_zstd_level = true;
visit_type_uint8(v, param, &p->multifd_zstd_level, &err);
break;
+ case MIGRATION_PARAMETER_ZERO_PAGE_DETECTION:
+ p->has_zero_page_detection = true;
+ visit_type_ZeroPageDetection(v, param, &p->zero_page_detection, &err);
+ break;
case MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE:
p->has_xbzrle_cache_size = true;
if (!visit_type_size(v, param, &cache_size, &err)) {
@@ -179,6 +179,9 @@ Property migration_properties[] = {
DEFINE_PROP_MIG_MODE("mode", MigrationState,
parameters.mode,
MIG_MODE_NORMAL),
+ DEFINE_PROP_ZERO_PAGE_DETECTION("zero-page-detection", MigrationState,
+ parameters.zero_page_detection,
+ ZERO_PAGE_DETECTION_LEGACY),
/* Migration capabilities */
DEFINE_PROP_MIG_CAP("x-xbzrle", MIGRATION_CAPABILITY_XBZRLE),
@@ -938,6 +941,13 @@ uint64_t migrate_xbzrle_cache_size(void)
return s->parameters.xbzrle_cache_size;
}
+ZeroPageDetection migrate_zero_page_detection(void)
+{
+ MigrationState *s = migrate_get_current();
+
+ return s->parameters.zero_page_detection;
+}
+
/* parameter setters */
void migrate_set_block_incremental(bool value)
@@ -1048,6 +1058,8 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp)
params->vcpu_dirty_limit = s->parameters.vcpu_dirty_limit;
params->has_mode = true;
params->mode = s->parameters.mode;
+ params->has_zero_page_detection = true;
+ params->zero_page_detection = s->parameters.zero_page_detection;
return params;
}
@@ -1084,6 +1096,7 @@ void migrate_params_init(MigrationParameters *params)
params->has_x_vcpu_dirty_limit_period = true;
params->has_vcpu_dirty_limit = true;
params->has_mode = true;
+ params->has_zero_page_detection = true;
}
/*
@@ -1398,6 +1411,10 @@ static void migrate_params_test_apply(MigrateSetParameters *params,
if (params->has_mode) {
dest->mode = params->mode;
}
+
+ if (params->has_zero_page_detection) {
+ dest->zero_page_detection = params->zero_page_detection;
+ }
}
static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
@@ -1548,6 +1565,10 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
if (params->has_mode) {
s->parameters.mode = params->mode;
}
+
+ if (params->has_zero_page_detection) {
+ s->parameters.zero_page_detection = params->zero_page_detection;
+ }
}
void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp)
@@ -1140,6 +1140,10 @@ static int save_zero_page(RAMState *rs, PageSearchStatus *pss,
QEMUFile *file = pss->pss_channel;
int len = 0;
+ if (migrate_zero_page_detection() == ZERO_PAGE_DETECTION_NONE) {
+ return 0;
+ }
+
if (!buffer_is_zero(p, TARGET_PAGE_SIZE)) {
return 0;
}