From patchwork Tue Mar 24 20:51:00 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yaniv Kamay X-Patchwork-Id: 14098 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n2OKpGT7030322 for ; Tue, 24 Mar 2009 20:51:17 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753512AbZCXUvP (ORCPT ); Tue, 24 Mar 2009 16:51:15 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753392AbZCXUvO (ORCPT ); Tue, 24 Mar 2009 16:51:14 -0400 Received: from mx2.redhat.com ([66.187.237.31]:53619 "EHLO mx2.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753164AbZCXUvM (ORCPT ); Tue, 24 Mar 2009 16:51:12 -0400 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n2OKp2Pc006654 for ; Tue, 24 Mar 2009 16:51:02 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n2OKoumN022426 for ; Tue, 24 Mar 2009 16:50:57 -0400 Received: from [10.35.1.39] (dhcp-1-39.tlv.redhat.com [10.35.1.39]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n2OKp1L8010005 for ; Tue, 24 Mar 2009 16:51:02 -0400 Message-ID: <49C947B4.5030503@redhat.com> Date: Tue, 24 Mar 2009 22:51:00 +0200 From: Yaniv Kamay User-Agent: Thunderbird 2.0.0.18 (X11/20081119) MIME-Version: 1.0 To: kvm@vger.kernel.org Subject: [PATCH] qemu: fix physical memory migration X-Scanned-By: MIMEDefang 2.58 on 172.16.27.26 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Hi, Attaching patch that: 1. Fix physical memory live migration. - Stop dirty memory tracking after completion of memory transfer. - In stage 3, updating dirty memory bits before collecting remaining dirty blocks in order to prevent missing dirty blokes in the range of current_addr to phys_ram_size while no dirty blocks exist in the range 0 - (current_addr - 1) 2. Improve migration error handling Thanks, Yaniv From d565b6b2246b0ac7c8ca292680f9134edb35caa7 Mon Sep 17 00:00:00 2001 From: Yaniv Kamay Date: Tue, 24 Mar 2009 20:12:35 +0200 Subject: [PATCH] qemu: fix physical memory migration --- qemu/hw/hw.h | 1 + qemu/migration.c | 7 ++++++- qemu/savevm.c | 5 +++++ qemu/vl.c | 19 +++++++++++++++---- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/qemu/hw/hw.h b/qemu/hw/hw.h index eab7bb4..6aad964 100644 --- a/qemu/hw/hw.h +++ b/qemu/hw/hw.h @@ -67,6 +67,7 @@ unsigned int qemu_get_be32(QEMUFile *f); uint64_t qemu_get_be64(QEMUFile *f); int qemu_file_rate_limit(QEMUFile *f); int qemu_file_has_error(QEMUFile *f); +void qemu_file_set_has_error(QEMUFile *f); /* Try to send any outstanding data. This function is useful when output is * halted due to rate limiting or EAGAIN errors occur as it can be used to diff --git a/qemu/migration.c b/qemu/migration.c index b3904b2..1cee6e9 100644 --- a/qemu/migration.c +++ b/qemu/migration.c @@ -225,7 +225,12 @@ void migrate_fd_put_ready(void *opaque) bdrv_flush_all(); qemu_savevm_state_complete(s->file); - s->state = MIG_STATE_COMPLETED; + if (qemu_file_has_error(s->file)) { + vm_start(); + s->state = MIG_STATE_ERROR; + } else { + s->state = MIG_STATE_COMPLETED; + } migrate_fd_cleanup(s); } } diff --git a/qemu/savevm.c b/qemu/savevm.c index 72c3709..7cd312d 100644 --- a/qemu/savevm.c +++ b/qemu/savevm.c @@ -370,6 +370,11 @@ int qemu_file_has_error(QEMUFile *f) return f->has_error; } +void qemu_file_set_has_error(QEMUFile *f) +{ + f->has_error = 1; +} + void qemu_fflush(QEMUFile *f) { if (!f->put_buffer) diff --git a/qemu/vl.c b/qemu/vl.c index 7ae266e..405212f 100644 --- a/qemu/vl.c +++ b/qemu/vl.c @@ -3221,8 +3221,14 @@ static int ram_save_block(QEMUFile *f) int found = 0; while (addr < phys_ram_size) { - if (kvm_enabled() && current_addr == 0) - kvm_update_dirty_pages_log(); /* FIXME: propagate errors */ + if (kvm_enabled() && current_addr == 0) { + int r; + if ((r = kvm_update_dirty_pages_log())) { + printf("%s: update dirty pages log failed %d\n", __FUNCTION__, r); + qemu_file_set_has_error(f); // for now: replacing FIXME with ugly hack + return 0; + } + } if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) { uint8_t ch; @@ -3293,10 +3299,15 @@ static int ram_save_live(QEMUFile *f, int stage, void *opaque) /* try transferring iterative blocks of memory */ if (stage == 3) { - cpu_physical_memory_set_dirty_tracking(0); - + int r; + if ((r = kvm_update_dirty_pages_log())) { + printf("%s: update dirty pages log failed %d\n", __FUNCTION__, r); + qemu_file_set_has_error(f); + return 0; + } /* flush all remaining blocks regardless of rate limiting */ while (ram_save_block(f) != 0); + cpu_physical_memory_set_dirty_tracking(0); } qemu_put_be64(f, RAM_SAVE_FLAG_EOS); -- 1.6.0.2