From patchwork Mon Jul 25 14:02:53 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Avi Kivity X-Patchwork-Id: 106703 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 9F4C9B6FAF for ; Tue, 26 Jul 2011 01:24:23 +1000 (EST) Received: from localhost ([::1]:52562 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QlLlc-0006cC-Cu for incoming@patchwork.ozlabs.org; Mon, 25 Jul 2011 10:04:20 -0400 Received: from eggs.gnu.org ([140.186.70.92]:47374) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QlLkd-0003zY-SV for qemu-devel@nongnu.org; Mon, 25 Jul 2011 10:03:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QlLkU-000538-Bb for qemu-devel@nongnu.org; Mon, 25 Jul 2011 10:03:19 -0400 Received: from mx1.redhat.com ([209.132.183.28]:11793) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QlLkU-00051q-3b for qemu-devel@nongnu.org; Mon, 25 Jul 2011 10:03:10 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p6PE39Qi021761 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 25 Jul 2011 10:03:09 -0400 Received: from cleopatra.tlv.redhat.com (cleopatra.tlv.redhat.com [10.35.255.11]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p6PE383b015530; Mon, 25 Jul 2011 10:03:08 -0400 Received: from s01.tlv.redhat.com (s01.tlv.redhat.com [10.35.255.8]) by cleopatra.tlv.redhat.com (Postfix) with ESMTP id EB4EA250B42; Mon, 25 Jul 2011 17:03:06 +0300 (IDT) From: Avi Kivity To: qemu-devel@nongnu.org Date: Mon, 25 Jul 2011 17:02:53 +0300 Message-Id: <1311602584-23409-13-git-send-email-avi@redhat.com> In-Reply-To: <1311602584-23409-1-git-send-email-avi@redhat.com> References: <1311602584-23409-1-git-send-email-avi@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: kvm@vger.kernel.org Subject: [Qemu-devel] [PATCH 12/23] memory: separate building the final memory map into two steps 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 Instead of adding and deleting regions in one pass, do a delete pass followed by an add pass. This fixes the following case: from: 0x0000-0x0fff ram (a1) 0x1000-0x1fff mmio (a2) 0x2000-0x2fff ram (a3) to: 0x0000-0x2fff ram (b1) The single pass algorithm removed a1, added b2, then removed a2 and a2, which caused the wrong memory map to be built. The two pass algorithm removes a1, a2, and a3, then adds b1. Signed-off-by: Avi Kivity --- memory.c | 38 +++++++++++++++++++++++++++++--------- 1 files changed, 29 insertions(+), 9 deletions(-) diff --git a/memory.c b/memory.c index a5cde0c..009ad33 100644 --- a/memory.c +++ b/memory.c @@ -546,10 +546,11 @@ static void address_space_update_ioeventfds(AddressSpace *as) as->ioeventfd_nb = ioeventfd_nb; } -static void address_space_update_topology(AddressSpace *as) +static void address_space_update_topology_pass(AddressSpace *as, + FlatView old_view, + FlatView new_view, + bool adding) { - FlatView old_view = as->current_map; - FlatView new_view = generate_memory_topology(as->root); unsigned iold, inew; FlatRange *frold, *frnew; @@ -576,15 +577,20 @@ static void address_space_update_topology(AddressSpace *as) && !flatrange_equal(frold, frnew)))) { /* In old, but (not in new, or in new but attributes changed). */ - as->ops->range_del(as, frold); + if (!adding) { + as->ops->range_del(as, frold); + } + ++iold; } else if (frold && frnew && flatrange_equal(frold, frnew)) { /* In both (logging may have changed) */ - if (frold->dirty_log_mask && !frnew->dirty_log_mask) { - as->ops->log_stop(as, frnew); - } else if (frnew->dirty_log_mask && !frold->dirty_log_mask) { - as->ops->log_start(as, frnew); + if (adding) { + if (frold->dirty_log_mask && !frnew->dirty_log_mask) { + as->ops->log_stop(as, frnew); + } else if (frnew->dirty_log_mask && !frold->dirty_log_mask) { + as->ops->log_start(as, frnew); + } } ++iold; @@ -592,10 +598,24 @@ static void address_space_update_topology(AddressSpace *as) } else { /* In new */ - as->ops->range_add(as, frnew); + if (adding) { + as->ops->range_add(as, frnew); + } + ++inew; } } +} + + +static void address_space_update_topology(AddressSpace *as) +{ + FlatView old_view = as->current_map; + FlatView new_view = generate_memory_topology(as->root); + + address_space_update_topology_pass(as, old_view, new_view, false); + address_space_update_topology_pass(as, old_view, new_view, true); + as->current_map = new_view; flatview_destroy(&old_view); address_space_update_ioeventfds(as);