]> git.proxmox.com Git - qemu.git/blobdiff - migration.c
add a header file for atomic operations
[qemu.git] / migration.c
index 64d8e4644e4cd64d0d580163fc096e55203f7f1d..635a7e7a08be67d194cc612d69b2fc36d6286a20 100644 (file)
@@ -66,6 +66,7 @@ MigrationState *migrate_get_current(void)
         .state = MIG_STATE_SETUP,
         .bandwidth_limit = MAX_THROTTLE,
         .xbzrle_cache_size = DEFAULT_MIGRATE_CACHE_SIZE,
+        .mbps = -1,
     };
 
     return &current_migration;
@@ -99,7 +100,7 @@ static void process_incoming_migration_co(void *opaque)
     qemu_fclose(f);
     if (ret < 0) {
         fprintf(stderr, "load of migration failed\n");
-        exit(0);
+        exit(EXIT_FAILURE);
     }
     qemu_announce_self();
     DPRINTF("successfully loaded vm state\n");
@@ -121,7 +122,7 @@ void process_incoming_migration(QEMUFile *f)
     int fd = qemu_get_fd(f);
 
     assert(fd != -1);
-    socket_set_nonblock(fd);
+    qemu_set_nonblock(fd);
     qemu_coroutine_enter(co, f);
 }
 
@@ -197,10 +198,11 @@ MigrationInfo *qmp_query_migrate(Error **errp)
         info->ram->remaining = ram_bytes_remaining();
         info->ram->total = ram_bytes_total();
         info->ram->duplicate = dup_mig_pages_transferred();
+        info->ram->skipped = skipped_mig_pages_transferred();
         info->ram->normal = norm_mig_pages_transferred();
         info->ram->normal_bytes = norm_mig_bytes_transferred();
         info->ram->dirty_pages_rate = s->dirty_pages_rate;
-
+        info->ram->mbps = s->mbps;
 
         if (blk_mig_active()) {
             info->has_disk = true;
@@ -227,8 +229,10 @@ MigrationInfo *qmp_query_migrate(Error **errp)
         info->ram->remaining = 0;
         info->ram->total = ram_bytes_total();
         info->ram->duplicate = dup_mig_pages_transferred();
+        info->ram->skipped = skipped_mig_pages_transferred();
         info->ram->normal = norm_mig_pages_transferred();
         info->ram->normal_bytes = norm_mig_bytes_transferred();
+        info->ram->mbps = s->mbps;
         break;
     case MIG_STATE_ERROR:
         info->has_status = true;
@@ -270,17 +274,14 @@ static void migrate_fd_cleanup(void *opaque)
 
     if (s->file) {
         DPRINTF("closing file\n");
-        qemu_fclose(s->file);
-        s->file = NULL;
-
         qemu_mutex_unlock_iothread();
         qemu_thread_join(&s->thread);
         qemu_mutex_lock_iothread();
 
-        migrate_fd_close(s);
+        qemu_fclose(s->file);
+        s->file = NULL;
     }
 
-    assert(s->migration_file == NULL);
     assert(s->state != MIG_STATE_ACTIVE);
 
     if (s->state != MIG_STATE_COMPLETED) {
@@ -292,8 +293,7 @@ static void migrate_fd_cleanup(void *opaque)
 
 static void migrate_finish_set_state(MigrationState *s, int new_state)
 {
-    if (__sync_val_compare_and_swap(&s->state, MIG_STATE_ACTIVE,
-                                    new_state) == new_state) {
+    if (atomic_cmpxchg(&s->state, MIG_STATE_ACTIVE, new_state) == new_state) {
         trace_migrate_set_state(new_state);
     }
 }
@@ -314,16 +314,6 @@ static void migrate_fd_cancel(MigrationState *s)
     migrate_finish_set_state(s, MIG_STATE_CANCELLED);
 }
 
-int migrate_fd_close(MigrationState *s)
-{
-    int rc = 0;
-    if (s->migration_file != NULL) {
-        rc = qemu_fclose(s->migration_file);
-        s->migration_file = NULL;
-    }
-    return rc;
-}
-
 void add_migration_state_change_notifier(Notifier *notify)
 {
     notifier_list_add(&migration_state_notifiers, notify);
@@ -361,7 +351,6 @@ static MigrationState *migrate_init(const MigrationParams *params)
            sizeof(enabled_capabilities));
 
     memset(s, 0, sizeof(*s));
-    s->bandwidth_limit = bandwidth_limit;
     s->params = *params;
     memcpy(s->enabled_capabilities, enabled_capabilities,
            sizeof(enabled_capabilities));
@@ -486,64 +475,39 @@ void qmp_migrate_set_downtime(double value, Error **errp)
     max_downtime = (uint64_t)value;
 }
 
-int migrate_use_xbzrle(void)
+bool migrate_rdma_pin_all(void)
 {
     MigrationState *s;
 
     s = migrate_get_current();
 
-    return s->enabled_capabilities[MIGRATION_CAPABILITY_XBZRLE];
+    return s->enabled_capabilities[MIGRATION_CAPABILITY_X_RDMA_PIN_ALL];
 }
 
-int64_t migrate_xbzrle_cache_size(void)
+int migrate_use_xbzrle(void)
 {
     MigrationState *s;
 
     s = migrate_get_current();
 
-    return s->xbzrle_cache_size;
+    return s->enabled_capabilities[MIGRATION_CAPABILITY_XBZRLE];
 }
 
-/* migration thread support */
-
-static int migration_put_buffer(void *opaque, const uint8_t *buf,
-                               int64_t pos, int size)
+int64_t migrate_xbzrle_cache_size(void)
 {
-    MigrationState *s = opaque;
-    int ret;
-
-    DPRINTF("putting %d bytes at %" PRId64 "\n", size, pos);
-
-    if (size <= 0) {
-        return size;
-    }
-
-    qemu_put_buffer(s->migration_file, buf, size);
-    ret = qemu_file_get_error(s->migration_file);
-    if (ret) {
-        return ret;
-    }
+    MigrationState *s;
 
-    return size;
-}
+    s = migrate_get_current();
 
-static int migration_close(void *opaque)
-{
-    return 0;
+    return s->xbzrle_cache_size;
 }
 
-static int migration_get_fd(void *opaque)
-{
-    MigrationState *s = opaque;
-
-    return qemu_get_fd(s->migration_file);
-}
+/* migration thread support */
 
 static void *migration_thread(void *opaque)
 {
     MigrationState *s = opaque;
     int64_t initial_time = qemu_get_clock_ms(rt_clock);
-    int64_t sleep_time = 0;
     int64_t initial_bytes = 0;
     int64_t max_size = 0;
     int64_t start_time = initial_time;
@@ -586,10 +550,13 @@ static void *migration_thread(void *opaque)
         current_time = qemu_get_clock_ms(rt_clock);
         if (current_time >= initial_time + BUFFER_DELAY) {
             uint64_t transferred_bytes = qemu_ftell(s->file) - initial_bytes;
-            uint64_t time_spent = current_time - initial_time - sleep_time;
+            uint64_t time_spent = current_time - initial_time;
             double bandwidth = transferred_bytes / time_spent;
             max_size = bandwidth * migrate_max_downtime() / 1000000;
 
+            s->mbps = time_spent ? (((double) transferred_bytes * 8.0) /
+                    ((double) time_spent / 1000.0)) / 1000.0 / 1000.0 : -1;
+
             DPRINTF("transferred %" PRIu64 " time_spent %" PRIu64
                     " bandwidth %g max_size %" PRId64 "\n",
                     transferred_bytes, time_spent, bandwidth, max_size);
@@ -600,14 +567,12 @@ static void *migration_thread(void *opaque)
             }
 
             qemu_file_reset_rate_limit(s->file);
-            sleep_time = 0;
             initial_time = current_time;
             initial_bytes = qemu_ftell(s->file);
         }
         if (qemu_file_rate_limit(s->file)) {
             /* usleep expects microseconds */
             g_usleep((initial_time + BUFFER_DELAY - current_time)*1000);
-            sleep_time += qemu_get_clock_ms(rt_clock) - current_time;
         }
     }
 
@@ -628,12 +593,6 @@ static void *migration_thread(void *opaque)
     return NULL;
 }
 
-static const QEMUFileOps migration_file_ops = {
-    .get_fd =         migration_get_fd,
-    .put_buffer =     migration_put_buffer,
-    .close =          migration_close,
-};
-
 void migrate_fd_connect(MigrationState *s)
 {
     s->state = MIG_STATE_ACTIVE;
@@ -642,7 +601,6 @@ void migrate_fd_connect(MigrationState *s)
     /* This is a best 1st approximation. ns to ms */
     s->expected_downtime = max_downtime/1000000;
     s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup, s);
-    s->file = qemu_fopen_ops(s, &migration_file_ops);
 
     qemu_file_set_rate_limit(s->file,
                              s->bandwidth_limit / XFER_LIMIT_RATIO);