From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:52413) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QlfmR-0000Ue-C8 for qemu-devel@nongnu.org; Tue, 26 Jul 2011 07:26:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QlfmP-0008Gm-9Z for qemu-devel@nongnu.org; Tue, 26 Jul 2011 07:26:31 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44664) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QlfmP-0008Fh-0i for qemu-devel@nongnu.org; Tue, 26 Jul 2011 07:26:29 -0400 From: Avi Kivity Date: Tue, 26 Jul 2011 14:26:12 +0300 Message-Id: <1311679582-11211-14-git-send-email-avi@redhat.com> In-Reply-To: <1311679582-11211-1-git-send-email-avi@redhat.com> References: <1311679582-11211-1-git-send-email-avi@redhat.com> Subject: [Qemu-devel] [PATCH v2 13/23] memory: separate building the final memory map into two steps List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Anthony Liguori , qemu-devel@nongnu.org Cc: kvm@vger.kernel.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 a3, 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 686bbf2..7a5670e 100644 --- a/memory.c +++ b/memory.c @@ -549,10 +549,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; @@ -579,15 +580,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; @@ -595,10 +601,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); -- 1.7.5.3