@samitouri / QOSamiQemu / commits / 468e507485

migration/qapi: Introduce system-wide "remaining" reports

Currently, mgmt can only query for remaining RAM using QMP command "query-migrate" and monitor the "ram" section. There's no way to report system-wide remaining data including VFIO devices. It was not a problem before, because for a very long time RAM was the only part that matters. After VFIO migrations landed upstream, it may not be enough. There can be GPU devices that contain GBs of device states. Mgmt may want to know how much remaining for special devices like VFIO, because all of them will be accounted as VM data to migrate and will contribute to downtime in the switchover phase. Add a new "remaining" field in query-migrate results on the top level, reflecting system-wide remaining data, which will include everything like VFIO devices. This information will be useful for mgmt to implement generic way of stall detection that covers all system resources. For example, when system-wide remaining data (especially, if sampled right after each migration iteration) does not decrease anymore for a relatively long period of time, then it may imply there is a challenge of converging, mgmt can react based on how this value changes over time. Before this patch, "expected_downtime" almost played this role. For example, by monitoring "expected_downtime" at the beginning of each iteration can in most cases also reflect the progress of migration system-wide. Said that, "expected_downtime" was always calculated based on a bandwidth value that can fluctuate if avail-switchover-bandwidth is not used. This new "remaining" field will remove that part of uncertainty for mgmt no matter if avail-switchover-bandwidth is used by the mgmt. With the new field, HMP "info migrate" now reports this: (qemu) info migrate Status: active Time (ms): total=12080, setup=14, exp_down=300 Remaining: 1.36 GiB <--- this is the new line RAM info: Throughput (Mbps): 840.50 Sizes: pagesize=4 KiB, total=4.02 GiB Transfers: transferred=1.18 GiB, remain=1.36 GiB Channels: precopy=1.18 GiB, multifd=0 B, postcopy=0 B Page Types: normal=307923, zero=388148 Page Rates (pps): transfer=25660 Others: dirty_syncs=1 When VFIO is not involved, the value reported in the new field should be approximately the same as reported in the "remaining" field of the RAM section. It is only approximately because the system-wide remaining data is a cached value, which gets frequently updated by migration core. OTOH, the RAM's remaining data is accurate. When VFIO is involved, the new value reported should normally be larger, because it will include the size of VFIO remaining data too. Cc: Aseef Imran <aimran@redhat.com> Reviewed-by: Juraj Marcin <jmarcin@redhat.com> Reviewed-by: Dr. David Alan Gilbert <dave@treblig.org> Acked-by: Markus Armbruster <armbru@redhat.com> # QAPI schema Link: https://lore.kernel.org/r/20260421202110.306051-15-peterx@redhat.com Signed-off-by: Peter Xu <peterx@redhat.com>

Peter Xu committed Apr 7, 2026 at 15:13 UTC 468e507485c2c180371c9dafbd5e9ce65c10a4b9
3 files changed +16
migration/migration-hmp-cmds.c
+5
@@ -178,6 +178,11 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
178 }
179 }
180
181 + if (info->has_remaining) {
182 + g_autofree char *remaining = size_to_str(info->remaining);
183 + monitor_printf(mon, "Remaining: \t\t%s\n", remaining);
184 + }
185 +
186 if (info->has_socket_address) {
187 SocketAddressList *addr;
188
migration/migration.c
+7
@@ -1076,6 +1076,12 @@ static void populate_time_info(MigrationInfo *info, MigrationState *s)
1076 }
1077 }
1078
1079 +static void populate_global_info(MigrationInfo *info, MigrationState *s)
1080 +{
1081 + info->has_remaining = true;
1082 + info->remaining = qatomic_read(&mig_stats.dirty_bytes_total);
1083 +}
1084 +
1085 static void populate_ram_info(MigrationInfo *info, MigrationState *s)
1086 {
1087 size_t page_size = qemu_target_page_size();
@@ -1177,6 +1183,7 @@ static void fill_source_migration_info(MigrationInfo *info)
1183 /* TODO add some postcopy stats */
1184 populate_time_info(info, s);
1185 populate_ram_info(info, s);
1186 + populate_global_info(info, s);
1187 migration_populate_vfio_info(info);
1188 break;
1189 case MIGRATION_STATUS_COLO:
qapi/migration.json
+4
@@ -300,6 +300,9 @@
300 # average memory load of the virtual CPU indirectly. Note that
301 # zero means guest doesn't dirty memory. (Since 8.1)
302 #
303 +# @remaining: amount of bytes remaining to be migrated system-wide,
304 +# includes both RAM and all devices (like VFIO). (Since 11.1)
305 +#
306 # Features:
307 #
308 # @unstable: Members @postcopy-latency, @postcopy-vcpu-latency,
@@ -310,6 +313,7 @@
313 ##
314 { 'struct': 'MigrationInfo',
315 'data': {'*status': 'MigrationStatus', '*ram': 'MigrationRAMStats',
316 + '*remaining': 'size',
317 '*vfio': 'VfioStats',
318 '*xbzrle-cache': 'XBZRLECacheStats',
319 '*total-time': 'int',