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

Merge remote-tracking branch 'remotes/juanquintela/tags/pull-migration-pull-request' into staging

Migration pull request

# gpg: Signature made Thu 13 Feb 2020 13:04:43 GMT
# gpg: using RSA key 1899FF8EDEBF58CCEE034B82F487EF185872D723
# gpg: Good signature from "Juan Quintela <quintela@redhat.com>" [full]
# gpg: aka "Juan Quintela <quintela@trasno.org>" [full]
# Primary key fingerprint: 1899 FF8E DEBF 58CC EE03 4B82 F487 EF18 5872 D723

* remotes/juanquintela/tags/pull-migration-pull-request:
git: Make submodule check only needed modules
migration-test: fix some memleaks in migration-test
tests/migration: Add some slack to auto converge
migration/rdma: rdma_accept_incoming_migration fix error handling
migration: Optimization about wait-unplug migration state
migration: Maybe VM is paused when migration is cancelled

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

+49 -42
+17 -9
migration/migration.c
··· 2797 2797 /* This block intentionally left blank */ 2798 2798 } 2799 2799 2800 - qemu_mutex_unlock_iothread(); 2801 - migrate_set_state(&s->state, *current_active_state, 2802 - MIGRATION_STATUS_PRE_SWITCHOVER); 2803 - qemu_sem_wait(&s->pause_sem); 2804 - migrate_set_state(&s->state, MIGRATION_STATUS_PRE_SWITCHOVER, 2805 - new_state); 2806 - *current_active_state = new_state; 2807 - qemu_mutex_lock_iothread(); 2800 + /* 2801 + * If the migration is cancelled when it is in the completion phase, 2802 + * the migration state is set to MIGRATION_STATUS_CANCELLING. 2803 + * So we don't need to wait a semaphore, otherwise we would always 2804 + * wait for the 'pause_sem' semaphore. 2805 + */ 2806 + if (s->state != MIGRATION_STATUS_CANCELLING) { 2807 + qemu_mutex_unlock_iothread(); 2808 + migrate_set_state(&s->state, *current_active_state, 2809 + MIGRATION_STATUS_PRE_SWITCHOVER); 2810 + qemu_sem_wait(&s->pause_sem); 2811 + migrate_set_state(&s->state, MIGRATION_STATUS_PRE_SWITCHOVER, 2812 + new_state); 2813 + *current_active_state = new_state; 2814 + qemu_mutex_lock_iothread(); 2815 + } 2808 2816 2809 2817 return s->state == new_state ? 0 : -EINVAL; 2810 2818 } ··· 3333 3341 3334 3342 qemu_savevm_state_setup(s->to_dst_file); 3335 3343 3336 - if (qemu_savevm_nr_failover_devices()) { 3344 + if (qemu_savevm_state_guest_unplug_pending()) { 3337 3345 migrate_set_state(&s->state, MIGRATION_STATUS_SETUP, 3338 3346 MIGRATION_STATUS_WAIT_UNPLUG); 3339 3347
+7 -4
migration/rdma.c
··· 3980 3980 RDMAContext *rdma = opaque; 3981 3981 int ret; 3982 3982 QEMUFile *f; 3983 - Error *local_err = NULL, **errp = &local_err; 3983 + Error *local_err = NULL; 3984 3984 3985 3985 trace_qemu_rdma_accept_incoming_migration(); 3986 3986 ret = qemu_rdma_accept(rdma); 3987 3987 3988 3988 if (ret) { 3989 - ERROR(errp, "RDMA Migration initialization failed!"); 3989 + fprintf(stderr, "RDMA ERROR: Migration initialization failed\n"); 3990 3990 return; 3991 3991 } 3992 3992 ··· 3998 3998 3999 3999 f = qemu_fopen_rdma(rdma, "rb"); 4000 4000 if (f == NULL) { 4001 - ERROR(errp, "could not qemu_fopen_rdma!"); 4001 + fprintf(stderr, "RDMA ERROR: could not qemu_fopen_rdma\n"); 4002 4002 qemu_rdma_cleanup(rdma); 4003 4003 return; 4004 4004 } 4005 4005 4006 4006 rdma->migration_started_on_destination = 1; 4007 - migration_fd_process_incoming(f, errp); 4007 + migration_fd_process_incoming(f, &local_err); 4008 + if (local_err) { 4009 + error_reportf_err(local_err, "RDMA ERROR:"); 4010 + } 4008 4011 } 4009 4012 4010 4013 void rdma_start_incoming_migration(const char *host_port, Error **errp)
+3 -21
migration/savevm.c
··· 1140 1140 } 1141 1141 } 1142 1142 1143 - int qemu_savevm_nr_failover_devices(void) 1143 + bool qemu_savevm_state_guest_unplug_pending(void) 1144 1144 { 1145 1145 SaveStateEntry *se; 1146 - int n = 0; 1147 1146 1148 1147 QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { 1149 1148 if (se->vmsd && se->vmsd->dev_unplug_pending && 1150 1149 se->vmsd->dev_unplug_pending(se->opaque)) { 1151 - n++; 1152 - } 1153 - } 1154 - 1155 - return n; 1156 - } 1157 - 1158 - bool qemu_savevm_state_guest_unplug_pending(void) 1159 - { 1160 - SaveStateEntry *se; 1161 - int n = 0; 1162 - 1163 - QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { 1164 - if (!se->vmsd || !se->vmsd->dev_unplug_pending) { 1165 - continue; 1166 - } 1167 - if (se->vmsd->dev_unplug_pending(se->opaque)) { 1168 - n++; 1150 + return true; 1169 1151 } 1170 1152 } 1171 1153 1172 - return n > 0; 1154 + return false; 1173 1155 } 1174 1156 1175 1157 void qemu_savevm_state_setup(QEMUFile *f)
-1
migration/savevm.h
··· 31 31 32 32 bool qemu_savevm_state_blocked(Error **errp); 33 33 void qemu_savevm_state_setup(QEMUFile *f); 34 - int qemu_savevm_nr_failover_devices(void); 35 34 bool qemu_savevm_state_guest_unplug_pending(void); 36 35 int qemu_savevm_state_resume_prepare(MigrationState *s); 37 36 void qemu_savevm_state_header(QEMUFile *f);
+8 -4
scripts/git-submodule.sh
··· 59 59 fi 60 60 61 61 test -f "$substat" || exit 1 62 - CURSTATUS=$($GIT submodule status $modules) 63 - OLDSTATUS=$(cat $substat) 64 - test "$CURSTATUS" = "$OLDSTATUS" 65 - exit $? 62 + for module in $modules; do 63 + CURSTATUS=$($GIT submodule status $module) 64 + OLDSTATUS=$(cat $substat | grep $module) 65 + if test "$CURSTATUS" != "$OLDSTATUS"; then 66 + exit 1 67 + fi 68 + done 69 + exit 0 66 70 ;; 67 71 update) 68 72 if test -z "$maybe_modules"
+14 -3
tests/qtest/migration-test.c
··· 498 498 const char *arch = qtest_get_arch(); 499 499 const char *machine_opts = NULL; 500 500 const char *memory_size; 501 + int ret = 0; 501 502 502 503 if (args->use_shmem) { 503 504 if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) { 504 505 g_test_skip("/dev/shm is not supported"); 505 - return -1; 506 + ret = -1; 507 + goto out; 506 508 } 507 509 } 508 510 ··· 611 613 g_free(shmem_path); 612 614 } 613 615 616 + out: 614 617 migrate_start_destroy(args); 615 - return 0; 618 + return ret; 616 619 } 617 620 618 621 static void test_migrate_end(QTestState *from, QTestState *to, bool test_dest) ··· 1134 1137 { 1135 1138 MigrateStart *args = migrate_start_new(); 1136 1139 1140 + g_free(args->opts_source); 1141 + g_free(args->opts_target); 1137 1142 args->opts_source = g_strdup("-uuid 11111111-1111-1111-1111-111111111111"); 1138 1143 args->opts_target = g_strdup("-uuid 11111111-1111-1111-1111-111111111111"); 1139 1144 do_test_validate_uuid(args, false); ··· 1143 1148 { 1144 1149 MigrateStart *args = migrate_start_new(); 1145 1150 1151 + g_free(args->opts_source); 1152 + g_free(args->opts_target); 1146 1153 args->opts_source = g_strdup("-uuid 11111111-1111-1111-1111-111111111111"); 1147 1154 args->opts_target = g_strdup("-uuid 22222222-2222-2222-2222-222222222222"); 1148 1155 args->hide_stderr = true; ··· 1153 1160 { 1154 1161 MigrateStart *args = migrate_start_new(); 1155 1162 1163 + g_free(args->opts_target); 1156 1164 args->opts_target = g_strdup("-uuid 22222222-2222-2222-2222-222222222222"); 1157 1165 args->hide_stderr = true; 1158 1166 do_test_validate_uuid(args, false); ··· 1162 1170 { 1163 1171 MigrateStart *args = migrate_start_new(); 1164 1172 1173 + g_free(args->opts_source); 1165 1174 args->opts_source = g_strdup("-uuid 11111111-1111-1111-1111-111111111111"); 1166 1175 args->hide_stderr = true; 1167 1176 do_test_validate_uuid(args, false); ··· 1237 1246 g_assert_cmpint(percentage, <=, max_pct); 1238 1247 1239 1248 remaining = read_ram_property_int(from, "remaining"); 1240 - g_assert_cmpint(remaining, <, expected_threshold); 1249 + g_assert_cmpint(remaining, <, 1250 + (expected_threshold + expected_threshold / 100)); 1241 1251 1242 1252 migrate_continue(from, "pre-switchover"); 1243 1253 ··· 1379 1389 " 'arguments': { 'uri': 'tcp:127.0.0.1:0' }}"); 1380 1390 qobject_unref(rsp); 1381 1391 1392 + g_free(uri); 1382 1393 uri = migrate_get_socket_address(to2, "socket-address"); 1383 1394 1384 1395 wait_for_migration_status(from, "cancelled", NULL);