qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

migration: introduce postcopy-only pending

There would be savevm states (dirty-bitmap) which can migrate only in
postcopy stage. The corresponding pending is introduced here.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-id: 20180313180320.339796-6-vsementsov@virtuozzo.com

authored by

Vladimir Sementsov-Ogievskiy and committed by
John Snow
47995026 4f43e953

+46 -26
+4 -3
hw/s390x/s390-stattrib.c
··· 183 183 } 184 184 185 185 static void cmma_save_pending(QEMUFile *f, void *opaque, uint64_t max_size, 186 - uint64_t *non_postcopiable_pending, 187 - uint64_t *postcopiable_pending) 186 + uint64_t *res_precopy_only, 187 + uint64_t *res_compatible, 188 + uint64_t *res_postcopy_only) 188 189 { 189 190 S390StAttribState *sas = S390_STATTRIB(opaque); 190 191 S390StAttribClass *sac = S390_STATTRIB_GET_CLASS(sas); 191 192 long long res = sac->get_dirtycount(sas); 192 193 193 194 if (res >= 0) { 194 - *non_postcopiable_pending += res; 195 + *res_precopy_only += res; 195 196 } 196 197 } 197 198
+15 -2
include/migration/register.h
··· 37 37 int (*save_setup)(QEMUFile *f, void *opaque); 38 38 void (*save_live_pending)(QEMUFile *f, void *opaque, 39 39 uint64_t threshold_size, 40 - uint64_t *non_postcopiable_pending, 41 - uint64_t *postcopiable_pending); 40 + uint64_t *res_precopy_only, 41 + uint64_t *res_compatible, 42 + uint64_t *res_postcopy_only); 43 + /* Note for save_live_pending: 44 + * - res_precopy_only is for data which must be migrated in precopy phase 45 + * or in stopped state, in other words - before target vm start 46 + * - res_compatible is for data which may be migrated in any phase 47 + * - res_postcopy_only is for data which must be migrated in postcopy phase 48 + * or in stopped state, in other words - after source vm stop 49 + * 50 + * Sum of res_postcopy_only, res_compatible and res_postcopy_only is the 51 + * whole amount of pending data. 52 + */ 53 + 54 + 42 55 LoadStateHandler *load_state; 43 56 int (*load_setup)(QEMUFile *f, void *opaque); 44 57 int (*load_cleanup)(void *opaque);
+4 -3
migration/block.c
··· 864 864 } 865 865 866 866 static void block_save_pending(QEMUFile *f, void *opaque, uint64_t max_size, 867 - uint64_t *non_postcopiable_pending, 868 - uint64_t *postcopiable_pending) 867 + uint64_t *res_precopy_only, 868 + uint64_t *res_compatible, 869 + uint64_t *res_postcopy_only) 869 870 { 870 871 /* Estimate pending number of bytes to send */ 871 872 uint64_t pending; ··· 886 887 887 888 DPRINTF("Enter save live pending %" PRIu64 "\n", pending); 888 889 /* We don't do postcopy */ 889 - *non_postcopiable_pending += pending; 890 + *res_precopy_only += pending; 890 891 } 891 892 892 893 static int block_load(QEMUFile *f, void *opaque, int version_id)
+6 -6
migration/migration.c
··· 2242 2242 */ 2243 2243 static MigIterateState migration_iteration_run(MigrationState *s) 2244 2244 { 2245 - uint64_t pending_size, pend_post, pend_nonpost; 2245 + uint64_t pending_size, pend_pre, pend_compat, pend_post; 2246 2246 bool in_postcopy = s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE; 2247 2247 2248 - qemu_savevm_state_pending(s->to_dst_file, s->threshold_size, 2249 - &pend_nonpost, &pend_post); 2250 - pending_size = pend_nonpost + pend_post; 2248 + qemu_savevm_state_pending(s->to_dst_file, s->threshold_size, &pend_pre, 2249 + &pend_compat, &pend_post); 2250 + pending_size = pend_pre + pend_compat + pend_post; 2251 2251 2252 2252 trace_migrate_pending(pending_size, s->threshold_size, 2253 - pend_post, pend_nonpost); 2253 + pend_pre, pend_compat, pend_post); 2254 2254 2255 2255 if (pending_size && pending_size >= s->threshold_size) { 2256 2256 /* Still a significant amount to transfer */ 2257 2257 if (migrate_postcopy() && !in_postcopy && 2258 - pend_nonpost <= s->threshold_size && 2258 + pend_pre <= s->threshold_size && 2259 2259 atomic_read(&s->start_postcopy)) { 2260 2260 if (postcopy_start(s)) { 2261 2261 error_report("%s: postcopy failed to start", __func__);
+5 -4
migration/ram.c
··· 2370 2370 } 2371 2371 2372 2372 static void ram_save_pending(QEMUFile *f, void *opaque, uint64_t max_size, 2373 - uint64_t *non_postcopiable_pending, 2374 - uint64_t *postcopiable_pending) 2373 + uint64_t *res_precopy_only, 2374 + uint64_t *res_compatible, 2375 + uint64_t *res_postcopy_only) 2375 2376 { 2376 2377 RAMState **temp = opaque; 2377 2378 RAMState *rs = *temp; ··· 2391 2392 2392 2393 if (migrate_postcopy_ram()) { 2393 2394 /* We can do postcopy, and all the data is postcopiable */ 2394 - *postcopiable_pending += remaining_size; 2395 + *res_compatible += remaining_size; 2395 2396 } else { 2396 - *non_postcopiable_pending += remaining_size; 2397 + *res_precopy_only += remaining_size; 2397 2398 } 2398 2399 } 2399 2400
+8 -5
migration/savevm.c
··· 1220 1220 * for units that can't do postcopy. 1221 1221 */ 1222 1222 void qemu_savevm_state_pending(QEMUFile *f, uint64_t threshold_size, 1223 - uint64_t *res_non_postcopiable, 1224 - uint64_t *res_postcopiable) 1223 + uint64_t *res_precopy_only, 1224 + uint64_t *res_compatible, 1225 + uint64_t *res_postcopy_only) 1225 1226 { 1226 1227 SaveStateEntry *se; 1227 1228 1228 - *res_non_postcopiable = 0; 1229 - *res_postcopiable = 0; 1229 + *res_precopy_only = 0; 1230 + *res_compatible = 0; 1231 + *res_postcopy_only = 0; 1230 1232 1231 1233 1232 1234 QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { ··· 1239 1241 } 1240 1242 } 1241 1243 se->ops->save_live_pending(f, se->opaque, threshold_size, 1242 - res_non_postcopiable, res_postcopiable); 1244 + res_precopy_only, res_compatible, 1245 + res_postcopy_only); 1243 1246 } 1244 1247 } 1245 1248
+3 -2
migration/savevm.h
··· 38 38 int qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only, 39 39 bool inactivate_disks); 40 40 void qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size, 41 - uint64_t *res_non_postcopiable, 42 - uint64_t *res_postcopiable); 41 + uint64_t *res_precopy_only, 42 + uint64_t *res_compatible, 43 + uint64_t *res_postcopy_only); 43 44 void qemu_savevm_send_ping(QEMUFile *f, uint32_t value); 44 45 void qemu_savevm_send_open_return_path(QEMUFile *f); 45 46 int qemu_savevm_send_packaged(QEMUFile *f, const uint8_t *buf, size_t len);
+1 -1
migration/trace-events
··· 86 86 migrate_fd_error(const char *error_desc) "error=%s" 87 87 migrate_fd_cancel(void) "" 88 88 migrate_handle_rp_req_pages(const char *rbname, size_t start, size_t len) "in %s at 0x%zx len 0x%zx" 89 - migrate_pending(uint64_t size, uint64_t max, uint64_t post, uint64_t nonpost) "pending size %" PRIu64 " max %" PRIu64 " (post=%" PRIu64 " nonpost=%" PRIu64 ")" 89 + migrate_pending(uint64_t size, uint64_t max, uint64_t pre, uint64_t compat, uint64_t post) "pending size %" PRIu64 " max %" PRIu64 " (pre = %" PRIu64 " compat=%" PRIu64 " post=%" PRIu64 ")" 90 90 migrate_send_rp_message(int msg_type, uint16_t len) "%d: len %d" 91 91 migration_completion_file_err(void) "" 92 92 migration_completion_postcopy_end(void) ""