From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60872) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X37VS-0007tL-OU for qemu-devel@nongnu.org; Fri, 04 Jul 2014 13:42:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X37VM-0008Tk-I7 for qemu-devel@nongnu.org; Fri, 04 Jul 2014 13:42:42 -0400 Received: from mx1.redhat.com ([209.132.183.28]:6481) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X37VM-0008TS-Ao for qemu-devel@nongnu.org; Fri, 04 Jul 2014 13:42:36 -0400 From: "Dr. David Alan Gilbert (git)" Date: Fri, 4 Jul 2014 18:41:31 +0100 Message-Id: <1404495717-4239-21-git-send-email-dgilbert@redhat.com> In-Reply-To: <1404495717-4239-1-git-send-email-dgilbert@redhat.com> References: <1404495717-4239-1-git-send-email-dgilbert@redhat.com> Subject: [Qemu-devel] [PATCH 20/46] Allow savevm handlers to state whether they could go into postcopy List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: aarcange@redhat.com, yamahata@private.email.ne.jp, lilei@linux.vnet.ibm.com, quintela@redhat.com From: "Dr. David Alan Gilbert" Use that to split the qemu_savevm_state_pending counts into postcopiable and non-postcopiable amounts Signed-off-by: Dr. David Alan Gilbert --- arch_init.c | 7 +++++++ include/migration/vmstate.h | 2 +- include/sysemu/sysemu.h | 4 +++- migration.c | 9 ++++++++- savevm.c | 23 +++++++++++++++++++---- 5 files changed, 38 insertions(+), 7 deletions(-) diff --git a/arch_init.c b/arch_init.c index a3c468e..aeeaf37 100644 --- a/arch_init.c +++ b/arch_init.c @@ -1190,6 +1190,12 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) return ret; } +/* RAM's always up for postcopying */ +static bool ram_can_postcopy(void *opaque) +{ + return true; +} + static SaveVMHandlers savevm_ram_handlers = { .save_live_setup = ram_save_setup, .save_live_iterate = ram_save_iterate, @@ -1197,6 +1203,7 @@ static SaveVMHandlers savevm_ram_handlers = { .save_live_pending = ram_save_pending, .load_state = ram_load, .cancel = ram_migration_cancel, + .can_postcopy = ram_can_postcopy, }; void ram_mig_init(void) diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index 9a001bd..4991935 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -54,7 +54,7 @@ typedef struct SaveVMHandlers { /* This runs outside the iothread lock! */ int (*save_live_setup)(QEMUFile *f, void *opaque); uint64_t (*save_live_pending)(QEMUFile *f, void *opaque, uint64_t max_size); - + bool (*can_postcopy)(void *opaque); LoadStateHandler *load_state; } SaveVMHandlers; diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index abf0d63..dc53580 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -109,7 +109,9 @@ void qemu_savevm_state_begin(QEMUFile *f, int qemu_savevm_state_iterate(QEMUFile *f); void qemu_savevm_state_complete(QEMUFile *f); void qemu_savevm_state_cancel(void); -uint64_t qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size); +void qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size, + uint64_t *res_non_postcopiable, + uint64_t *res_postcopiable); void qemu_savevm_command_send(QEMUFile *f, enum qemu_vm_cmd command, uint16_t len, uint8_t *data); void qemu_savevm_send_reqack(QEMUFile *f, uint32_t value); diff --git a/migration.c b/migration.c index eac12ab..8343679 100644 --- a/migration.c +++ b/migration.c @@ -806,8 +806,15 @@ static void *migration_thread(void *opaque) uint64_t pending_size; if (!qemu_file_rate_limit(s->file)) { - pending_size = qemu_savevm_state_pending(s->file, max_size); + uint64_t pend_post, pend_nonpost; + DPRINTF("iterate\n"); + qemu_savevm_state_pending(s->file, max_size, &pend_nonpost, + &pend_post); + pending_size = pend_nonpost + pend_post; trace_migrate_pending(pending_size, max_size); + DPRINTF("pending size %" PRIu64 " max %" PRIu64 " (post=%" PRIu64 + " nonpost=%" PRIu64 ")\n", + pending_size, max_size, pend_post, pend_nonpost); if (pending_size && pending_size >= max_size) { qemu_savevm_state_iterate(s->file); } else { diff --git a/savevm.c b/savevm.c index 843443f..d8af526 100644 --- a/savevm.c +++ b/savevm.c @@ -903,10 +903,18 @@ void qemu_savevm_state_complete(QEMUFile *f) qemu_fflush(f); } -uint64_t qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size) +/* Give an estimate of the amount left to be transferred, + * the result is split into the amount for units that can and + * for units that can't do postcopy. + */ +void qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size, + uint64_t *res_non_postcopiable, + uint64_t *res_postcopiable) { SaveStateEntry *se; - uint64_t ret = 0; + uint64_t res_nonpc = 0; + uint64_t res_pc = 0; + uint64_t tmp; QTAILQ_FOREACH(se, &savevm_handlers, entry) { if (!se->ops || !se->ops->save_live_pending) { @@ -917,9 +925,16 @@ uint64_t qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size) continue; } } - ret += se->ops->save_live_pending(f, se->opaque, max_size); + tmp = se->ops->save_live_pending(f, se->opaque, max_size); + + if (se->ops->can_postcopy(se->opaque)) { + res_pc += tmp; + } else { + res_nonpc += tmp; + } } - return ret; + *res_non_postcopiable = res_nonpc; + *res_postcopiable = res_pc; } void qemu_savevm_state_cancel(void) -- 1.9.3