From: mrhines@linux.vnet.ibm.com
To: qemu-devel@nongnu.org
Cc: aliguori@us.ibm.com, quintela@redhat.com, owasserm@redhat.com,
onom@us.ibm.com, abali@us.ibm.com, mrhines@us.ibm.com,
gokul@us.ibm.com, pbonzini@redhat.com
Subject: [Qemu-devel] [RFC PATCH v1: 08/12] mc: modified QMP statistics and migration_thread handoff
Date: Mon, 21 Oct 2013 01:14:18 +0000 [thread overview]
Message-ID: <1382318062-6288-9-git-send-email-mrhines@linux.vnet.ibm.com> (raw)
In-Reply-To: <1382318062-6288-1-git-send-email-mrhines@linux.vnet.ibm.com>
From: "Michael R. Hines" <mrhines@us.ibm.com>
In addition to better handling of new QMP statistics associated
with the migration_bitmap and MC performance, we need to transfer
control from the migration thread to the MC thread more cleanly,
which means dynamically allocating the threads and doing
the handoff after the initial live migration has completed.
Signed-off-by: Michael R. Hines <mrhines@us.ibm.com>
---
hmp.c | 17 ++++++++
include/migration/migration.h | 14 ++++++-
migration.c | 94 +++++++++++++++++++++++++++----------------
qapi-schema.json | 2 +
savevm.c | 5 +--
5 files changed, 93 insertions(+), 39 deletions(-)
diff --git a/hmp.c b/hmp.c
index 32ee285..43896e9 100644
--- a/hmp.c
+++ b/hmp.c
@@ -202,6 +202,23 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
info->disk->total >> 10);
}
+ if (info->has_mc) {
+ monitor_printf(mon, "checkpoints: %" PRIu64 "\n",
+ info->mc->checkpoints);
+ monitor_printf(mon, "xmit_time: %" PRIu64 " ms\n",
+ info->mc->xmit_time);
+ monitor_printf(mon, "log_dirty_time: %" PRIu64 " ms\n",
+ info->mc->log_dirty_time);
+ monitor_printf(mon, "migration_bitmap_time: %" PRIu64 " ms\n",
+ info->mc->migration_bitmap_time);
+ monitor_printf(mon, "ram_copy_time: %" PRIu64 " ms\n",
+ info->mc->ram_copy_time);
+ monitor_printf(mon, "copy_mbps: %0.2f mbps\n",
+ info->mc->copy_mbps);
+ monitor_printf(mon, "throughput: %0.2f mbps\n",
+ info->mc->mbps);
+ }
+
if (info->has_xbzrle_cache) {
monitor_printf(mon, "cache size: %" PRIu64 " bytes\n",
info->xbzrle_cache->cache_size);
diff --git a/include/migration/migration.h b/include/migration/migration.h
index fcf7684..a1ab06c 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -35,13 +35,14 @@ struct MigrationState
int64_t bandwidth_limit;
size_t bytes_xfer;
size_t xfer_limit;
- QemuThread thread;
+ QemuThread *thread;
QEMUBH *cleanup_bh;
QEMUFile *file;
int state;
MigrationParams params;
double mbps;
+ double copy_mbps;
int64_t total_time;
int64_t downtime;
int64_t expected_downtime;
@@ -54,6 +55,7 @@ struct MigrationState
bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
int64_t xbzrle_cache_size;
int64_t setup_time;
+ int64_t checkpoints;
};
void process_incoming_migration(QEMUFile *f);
@@ -137,6 +139,12 @@ enum {
MIG_STATE_MC,
MIG_STATE_COMPLETED,
};
+
+int mc_enable_buffering(void);
+int mc_start_buffer(void);
+void mc_init_checkpointer(MigrationState *s);
+void mc_process_incoming_checkpoints_if_requested(QEMUFile *f);
+
void ram_handle_compressed(void *host, uint8_t ch, uint64_t size);
/**
@@ -207,10 +215,14 @@ int ram_control_copy_page(QEMUFile *f,
long size);
int migrate_use_mc(void);
+int migrate_use_mc_net(void);
int migrate_use_mc_rdma_copy(void);
#define MC_VERSION 1
+int mc_info_load(QEMUFile *f, void *opaque, int version_id);
+void mc_info_save(QEMUFile *f, void *opaque);
+
void qemu_rdma_info_save(QEMUFile *f, void *opaque);
int qemu_rdma_info_load(QEMUFile *f, void *opaque, int version_id);
#endif
diff --git a/migration.c b/migration.c
index 62dded3..8e0827e 100644
--- a/migration.c
+++ b/migration.c
@@ -172,6 +172,31 @@ static void get_xbzrle_cache_stats(MigrationInfo *info)
}
}
+static void get_ram_stats(MigrationState *s, MigrationInfo *info)
+{
+ info->has_total_time = true;
+ info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME)
+ - s->total_time;
+
+ info->has_ram = true;
+ info->ram = g_malloc0(sizeof(*info->ram));
+ info->ram->transferred = ram_bytes_transferred();
+ 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;
+
+ if (blk_mig_active()) {
+ info->has_disk = true;
+ info->disk = g_malloc0(sizeof(*info->disk));
+ info->disk->transferred = blk_mig_bytes_transferred();
+ info->disk->remaining = blk_mig_bytes_remaining();
+ info->disk->total = blk_mig_bytes_total();
+ }
+}
+
MigrationInfo *qmp_query_migrate(Error **errp)
{
MigrationInfo *info = g_malloc0(sizeof(*info));
@@ -197,26 +222,8 @@ MigrationInfo *qmp_query_migrate(Error **errp)
info->has_setup_time = true;
info->setup_time = s->setup_time;
- info->has_ram = true;
- info->ram = g_malloc0(sizeof(*info->ram));
- info->ram->transferred = ram_bytes_transferred();
- 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();
+ get_ram_stats(s, info);
info->ram->dirty_pages_rate = s->dirty_pages_rate;
- info->ram->mbps = s->mbps;
-
- if (blk_mig_active()) {
- info->has_disk = true;
- info->disk = g_malloc0(sizeof(*info->disk));
- info->disk->transferred = blk_mig_bytes_transferred();
- info->disk->remaining = blk_mig_bytes_remaining();
- info->disk->total = blk_mig_bytes_total();
- }
-
get_xbzrle_cache_stats(info);
break;
case MIG_STATE_COMPLETED:
@@ -225,22 +232,37 @@ MigrationInfo *qmp_query_migrate(Error **errp)
info->has_status = true;
info->status = g_strdup("completed");
info->has_total_time = true;
- info->total_time = s->total_time;
+ info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME)
+ - s->total_time;
info->has_downtime = true;
info->downtime = s->downtime;
info->has_setup_time = true;
info->setup_time = s->setup_time;
- info->has_ram = true;
- info->ram = g_malloc0(sizeof(*info->ram));
- info->ram->transferred = ram_bytes_transferred();
- 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;
+ get_ram_stats(s, info);
+ break;
+ case MIG_STATE_MC:
+ info->has_status = true;
+ info->status = g_strdup("checkpointing");
+ info->has_setup_time = true;
+ info->setup_time = s->setup_time;
+ info->has_downtime = true;
+ info->downtime = s->downtime;
+
+ get_ram_stats(s, info);
+ info->ram->dirty_pages_rate = s->dirty_pages_rate;
+ get_xbzrle_cache_stats(info);
+
+
+ info->has_mc = true;
+ info->mc = g_malloc0(sizeof(*info->mc));
+ info->mc->xmit_time = s->xmit_time;
+ info->mc->log_dirty_time = s->log_dirty_time;
+ info->mc->migration_bitmap_time = s->bitmap_time;
+ info->mc->ram_copy_time = s->ram_copy_time;
+ info->mc->copy_mbps = s->copy_mbps;
+ info->mc->mbps = s->mbps;
+ info->mc->checkpoints = s->checkpoints;
break;
case MIG_STATE_ERROR:
info->has_status = true;
@@ -288,14 +310,17 @@ static void migrate_fd_cleanup(void *opaque)
{
MigrationState *s = opaque;
- qemu_bh_delete(s->cleanup_bh);
- s->cleanup_bh = NULL;
+ if(s->cleanup_bh) {
+ qemu_bh_delete(s->cleanup_bh);
+ s->cleanup_bh = NULL;
+ }
if (s->file) {
DPRINTF("closing file\n");
qemu_mutex_unlock_iothread();
- qemu_thread_join(&s->thread);
+ qemu_thread_join(s->thread);
qemu_mutex_lock_iothread();
+ g_free(s->thread);
qemu_fclose(s->file);
s->file = NULL;
@@ -670,6 +695,7 @@ void migrate_fd_connect(MigrationState *s)
/* Notify before starting migration thread */
notifier_list_notify(&migration_state_notifiers, s);
- qemu_thread_create(&s->thread, migration_thread, s,
+ s->thread = g_malloc0(sizeof(*s->thread));
+ qemu_thread_create(s->thread, migration_thread, s,
QEMU_THREAD_JOINABLE);
}
diff --git a/qapi-schema.json b/qapi-schema.json
index 8e72bcf..e0a430c 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -630,6 +630,8 @@
# migration statistics, only returned if XBZRLE feature is on and
# status is 'active' or 'completed' (since 1.2)
#
+# @mc: #options @MCStats containing details Micro-Checkpointing statistics
+#
# @total-time: #optional total amount of milliseconds since migration started.
# If migration has ended, it returns the total migration
# time. (since 1.2)
diff --git a/savevm.c b/savevm.c
index f8eb225..3ad4eea 100644
--- a/savevm.c
+++ b/savevm.c
@@ -419,10 +419,7 @@ QEMUFile *qemu_fdopen(int fd, const char *mode)
{
QEMUFileSocket *s;
- if (mode == NULL ||
- (mode[0] != 'r' && mode[0] != 'w') ||
- mode[1] != 'b' || mode[2] != 0) {
- fprintf(stderr, "qemu_fdopen: Argument validity check failed\n");
+ if (qemu_file_mode_is_not_valid(mode)) {
return NULL;
}
--
1.8.1.2
next prev parent reply other threads:[~2013-10-21 1:15 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-21 1:14 [Qemu-devel] [RFC PATCH v1: 00/12] fault tolerance through micro-checkpointing mrhines
2013-10-21 1:14 ` [Qemu-devel] [RFC PATCH v1: 01/12] mc: add documentation for micro-checkpointing mrhines
2013-10-21 1:14 ` [Qemu-devel] [RFC PATCH v1: 02/12] rdma: remove reference to github.com mrhines
2013-10-21 1:14 ` [Qemu-devel] [RFC PATCH v1: 03/12] migration: introduce parallelization of migration_bitmap mrhines
2013-10-21 1:14 ` [Qemu-devel] [RFC PATCH v1: 04/12] mc: introduce a "checkpointing" status check into the VCPU states mrhines
2013-10-21 1:14 ` [Qemu-devel] [RFC PATCH v1: 05/12] migration: support custom page loading mrhines
2013-10-21 1:14 ` [Qemu-devel] [RFC PATCH v1: 06/12] rdma: accelerated memcpy() support mrhines
2013-10-21 1:14 ` [Qemu-devel] [RFC PATCH v1: 07/12] mc: introduce state machine error handling and migration_bitmap prep mrhines
2013-10-21 1:14 ` mrhines [this message]
2013-10-21 1:14 ` [Qemu-devel] [RFC PATCH v1: 09/12] mc: core logic mrhines
2013-10-21 1:14 ` [Qemu-devel] [RFC PATCH v1: 10/12] mc: configure and makefile support mrhines
2013-10-21 1:14 ` [Qemu-devel] [RFC PATCH v1: 11/12] mc: register MC qemu-file functions and expose MC tunable capability mrhines
2013-10-23 11:00 ` Isaku Yamahata
2013-11-06 16:34 ` Michael R. Hines
2013-11-07 2:38 ` Isaku Yamahata
2013-10-21 1:14 ` [Qemu-devel] [RFC PATCH v1: 12/12] mc: activate and use MC core logic if requested mrhines
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1382318062-6288-9-git-send-email-mrhines@linux.vnet.ibm.com \
--to=mrhines@linux.vnet.ibm.com \
--cc=abali@us.ibm.com \
--cc=aliguori@us.ibm.com \
--cc=gokul@us.ibm.com \
--cc=mrhines@us.ibm.com \
--cc=onom@us.ibm.com \
--cc=owasserm@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).