From patchwork Fri Mar 21 19:40:18 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Dr. David Alan Gilbert" X-Patchwork-Id: 332732 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 24DDA2C00B2 for ; Sat, 22 Mar 2014 06:41:08 +1100 (EST) Received: from localhost ([::1]:54445 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WR5JR-0005d0-4K for incoming@patchwork.ozlabs.org; Fri, 21 Mar 2014 15:41:05 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36444) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WR5J6-0005aw-En for qemu-devel@nongnu.org; Fri, 21 Mar 2014 15:40:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WR5J0-0005Qd-2k for qemu-devel@nongnu.org; Fri, 21 Mar 2014 15:40:44 -0400 Received: from mx1.redhat.com ([209.132.183.28]:41335) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WR5Iz-0005PB-Dg for qemu-devel@nongnu.org; Fri, 21 Mar 2014 15:40:37 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s2LJeWXd026930 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 21 Mar 2014 15:40:33 -0400 Received: from dgilbert-t530.home.treblig.org (vpn1-5-94.ams2.redhat.com [10.36.5.94]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s2LJeJ5b026040; Fri, 21 Mar 2014 15:40:19 -0400 From: "Dr. David Alan Gilbert (git)" To: qemu-devel@nongnu.org Date: Fri, 21 Mar 2014 19:40:18 +0000 Message-Id: <1395430818-17716-1-git-send-email-dgilbert@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: pbonzini@redhat.com, quintela@redhat.com Subject: [Qemu-devel] [PATCH v3 1/1] Count used RAMBlock pages for migration_dirty_pages X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: "Dr. David Alan Gilbert" This is a fix for a bug* triggered by a migration after hot unplugging a few virtio-net NICs, that caused migration never to converge, because 'migration_dirty_pages' is incorrectly initialised. 'migration_dirty_pages' is used as a tally of the number of outstanding dirty pages, to give the migration code an idea of how much more data will need to be transferred, and thus whether it can end the iterative phase. It was initialised to the total size of the RAMBlock address space, however hotunplug can leave this space sparse, and hence migration_dirty_pages ended up too large. Signed-off-by: Dr. David Alan Gilbert (* https://bugzilla.redhat.com/show_bug.cgi?id=1074913 ) --- arch_init.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) v3: Commit message only; fix up stupid copy-and-paste v2: Don't worry about RAMBlocks sharing a page; it doesn't happen diff --git a/arch_init.c b/arch_init.c index f18f42e..47a1e44 100644 --- a/arch_init.c +++ b/arch_init.c @@ -727,11 +727,8 @@ static void reset_ram_globals(void) static int ram_save_setup(QEMUFile *f, void *opaque) { RAMBlock *block; - int64_t ram_pages = last_ram_offset() >> TARGET_PAGE_BITS; + int64_t ram_bitmap_pages; /* Size of bitmap in pages, including gaps */ - migration_bitmap = bitmap_new(ram_pages); - bitmap_set(migration_bitmap, 0, ram_pages); - migration_dirty_pages = ram_pages; mig_throttle_on = false; dirty_rate_high_cnt = 0; @@ -770,6 +767,22 @@ static int ram_save_setup(QEMUFile *f, void *opaque) bytes_transferred = 0; reset_ram_globals(); + ram_bitmap_pages = last_ram_offset() >> TARGET_PAGE_BITS; + migration_bitmap = bitmap_new(ram_bitmap_pages); + bitmap_set(migration_bitmap, 0, ram_bitmap_pages); + + /* + * Count the total number of pages used by ram blocks not including any + * gaps due to alignment or unplugs. + */ + migration_dirty_pages = 0; + QTAILQ_FOREACH(block, &ram_list.blocks, next) { + uint64_t block_pages = 0; + + block_pages = (block->length + TARGET_PAGE_SIZE - 1) / TARGET_PAGE_SIZE; + migration_dirty_pages += block_pages; + } + memory_global_dirty_log_start(); migration_bitmap_sync(); qemu_mutex_unlock_iothread();