From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:39685) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RxEgH-0002z9-SX for qemu-devel@nongnu.org; Tue, 14 Feb 2012 04:28:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RxEg9-0003UR-Ic for qemu-devel@nongnu.org; Tue, 14 Feb 2012 04:28:13 -0500 Received: from mx1.redhat.com ([209.132.183.28]:10287) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RxEg9-0003U3-9n for qemu-devel@nongnu.org; Tue, 14 Feb 2012 04:28:05 -0500 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q1E9S4OD014690 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 14 Feb 2012 04:28:04 -0500 Received: from cleopatra.tlv.redhat.com (cleopatra.tlv.redhat.com [10.35.255.11]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q1E9S2av013201 for ; Tue, 14 Feb 2012 04:28:04 -0500 From: Avi Kivity Date: Tue, 14 Feb 2012 11:27:35 +0200 Message-Id: <1329211670-11548-6-git-send-email-avi@redhat.com> In-Reply-To: <1329211670-11548-1-git-send-email-avi@redhat.com> References: <1329211670-11548-1-git-send-email-avi@redhat.com> Subject: [Qemu-devel] [PATCH 05/20] memory: change memory registration to rebuild the memory map on each change List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Instead of incrementally building the memory map, rebuild it every time. This allows later simplification, since the code need not consider overlaying a previous mapping. It is also RCU friendly. With large memory guests this can get expensive, since the operation is O(mem size), but this will be optimized later. As a side effect subpage and L2 leaks are fixed here. Signed-off-by: Avi Kivity --- exec.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 49 insertions(+), 1 deletions(-) diff --git a/exec.c b/exec.c index 6726afd..b36c301 100644 --- a/exec.c +++ b/exec.c @@ -2520,6 +2520,53 @@ static subpage_t *subpage_init (target_phys_addr_t base, ram_addr_t *phys, } \ } while (0) +static void destroy_page_desc(PhysPageDesc pd) +{ + unsigned io_index = pd.phys_offset & ~TARGET_PAGE_MASK; + MemoryRegion *mr = io_mem_region[io_index]; + + if (mr->subpage) { + subpage_t *subpage = container_of(mr, subpage_t, iomem); + memory_region_destroy(&subpage->iomem); + g_free(subpage); + } +} + +static void destroy_l2_mapping(void **lp, unsigned level) +{ + unsigned i; + void **p; + PhysPageDesc *pd; + + if (!*lp) { + return; + } + + if (level > 0) { + p = *lp; + for (i = 0; i < L2_SIZE; ++i) { + destroy_l2_mapping(&p[i], level - 1); + } + g_free(p); + } else { + pd = *lp; + for (i = 0; i < L2_SIZE; ++i) { + destroy_page_desc(pd[i]); + } + g_free(pd); + } + *lp = NULL; +} + +static void destroy_all_mappings(void) +{ + unsigned i; + + for (i = 0; i < P_L1_SIZE; ++i) { + destroy_l2_mapping(&l1_phys_map[i], P_L1_SHIFT / L2_BITS - 1); + } +} + /* register physical memory. For RAM, 'size' must be a multiple of the target page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an @@ -3490,6 +3537,7 @@ static void io_mem_init(void) static void core_begin(MemoryListener *listener) { + destroy_all_mappings(); } static void core_commit(MemoryListener *listener) @@ -3505,12 +3553,12 @@ static void core_region_add(MemoryListener *listener, static void core_region_del(MemoryListener *listener, MemoryRegionSection *section) { - cpu_register_physical_memory_log(section, false); } static void core_region_nop(MemoryListener *listener, MemoryRegionSection *section) { + cpu_register_physical_memory_log(section, section->readonly); } static void core_log_start(MemoryListener *listener, -- 1.7.9