From patchwork Fri Sep 15 08:40:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 814164 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3xtq4x5JCdz9sPr for ; Fri, 15 Sep 2017 18:56:17 +1000 (AEST) Received: from localhost ([::1]:52023 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmQ3-0005yS-Qb for incoming@patchwork.ozlabs.org; Fri, 15 Sep 2017 04:56:15 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38434) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmBU-0007Jz-1p for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:41:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsmBO-0002df-Dp for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:41:12 -0400 Received: from ozlabs.ru ([107.173.13.209]:44990) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmBO-0002dY-7S for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:41:06 -0400 Received: from vpl1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 38A493A60028; Fri, 15 Sep 2017 04:41:49 -0400 (EDT) From: Alexey Kardashevskiy To: qemu-devel@nongnu.org Date: Fri, 15 Sep 2017 18:40:18 +1000 Message-Id: <20170915084030.40988-2-aik@ozlabs.ru> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170915084030.40988-1-aik@ozlabs.ru> References: <20170915084030.40988-1-aik@ozlabs.ru> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 107.173.13.209 Subject: [Qemu-devel] [PATCH qemu v2 01/13] memory: Postpone flatview and dispatch tree building till all devices are added X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , Paolo Bonzini Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Most devices use at least one address space and every time a new address space is added, flat views and dispatch trees are rebuild for all address spaces. This is not a problem for a relatively small amount of devices but even 50 virtio-pci devices use more than 8GB of RAM. What happens that on every flatview/dispatch rebuild, new arrays are allocated and old ones release but the release is done via RCU so until an entire machine is build, they are not released. This wraps devices creation into memory_region_transaction_begin/commit to massively reduce amount of flat view/dispatch tree (re)allocations. Signed-off-by: Alexey Kardashevskiy --- Changes: v2: * wrapped qemu_run_machine_init_done_notifiers() as well --- vl.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/vl.c b/vl.c index fb1f05b937..ee3cc7db48 100644 --- a/vl.c +++ b/vl.c @@ -4661,12 +4661,16 @@ int main(int argc, char **argv, char **envp) igd_gfx_passthru(); /* init generic devices */ + memory_region_transaction_begin(); + rom_set_order_override(FW_CFG_ORDER_OVERRIDE_DEVICE); if (qemu_opts_foreach(qemu_find_opts("device"), device_init_func, NULL, NULL)) { exit(1); } + memory_region_transaction_commit(); + cpu_synchronize_all_post_init(); rom_reset_order_override(); @@ -4749,8 +4753,13 @@ int main(int argc, char **argv, char **envp) /* TODO: once all bus devices are qdevified, this should be done * when bus is created by qdev.c */ qemu_register_reset(qbus_reset_all_fn, sysbus_get_default()); + + memory_region_transaction_begin(); + qemu_run_machine_init_done_notifiers(); + memory_region_transaction_commit(); + if (rom_check_and_register_reset() != 0) { error_report("rom check and register reset failed"); exit(1); From patchwork Fri Sep 15 08:40:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 814156 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3xtpsn3wRqz9sPr for ; Fri, 15 Sep 2017 18:46:37 +1000 (AEST) Received: from localhost ([::1]:51978 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmGh-0004Hb-II for incoming@patchwork.ozlabs.org; Fri, 15 Sep 2017 04:46:35 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38391) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmBQ-0007Gf-PV for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:41:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsmBP-0002e3-MV for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:41:08 -0400 Received: from ozlabs.ru ([107.173.13.209]:45004) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmBP-0002dp-F9 for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:41:07 -0400 Received: from vpl1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 839873A60042; Fri, 15 Sep 2017 04:41:50 -0400 (EDT) From: Alexey Kardashevskiy To: qemu-devel@nongnu.org Date: Fri, 15 Sep 2017 18:40:19 +1000 Message-Id: <20170915084030.40988-3-aik@ozlabs.ru> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170915084030.40988-1-aik@ozlabs.ru> References: <20170915084030.40988-1-aik@ozlabs.ru> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 107.173.13.209 Subject: [Qemu-devel] [PATCH qemu v2 02/13] exec: Explicitely export target AS from address_space_translate_internal X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , Paolo Bonzini Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This is not so mechanical change in order to move to shared FlatViews so make it a separate patch. The first argument of address_space_do_translate() will become a FlatView, however since address_space_get_iotlb_entry() still wants AS, hence this change. Signed-off-by: Alexey Kardashevskiy --- exec.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/exec.c b/exec.c index d20c34ca83..bd94248390 100644 --- a/exec.c +++ b/exec.c @@ -477,7 +477,8 @@ static MemoryRegionSection address_space_do_translate(AddressSpace *as, hwaddr *xlat, hwaddr *plen, bool is_write, - bool is_mmio) + bool is_mmio, + AddressSpace **target_as) { IOMMUTLBEntry iotlb; MemoryRegionSection *section; @@ -504,6 +505,7 @@ static MemoryRegionSection address_space_do_translate(AddressSpace *as, } as = iotlb.target_as; + *target_as = iotlb.target_as; } *xlat = addr; @@ -526,7 +528,7 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr, /* This can never be MMIO. */ section = address_space_do_translate(as, addr, &xlat, &plen, - is_write, false); + is_write, false, &as); /* Illegal translation */ if (section.mr == &io_mem_unassigned) { @@ -549,7 +551,7 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr, plen -= 1; return (IOMMUTLBEntry) { - .target_as = section.address_space, + .target_as = as, .iova = addr & ~plen, .translated_addr = xlat & ~plen, .addr_mask = plen, @@ -570,7 +572,8 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, MemoryRegionSection section; /* This can be MMIO, so setup MMIO bit. */ - section = address_space_do_translate(as, addr, xlat, plen, is_write, true); + section = address_space_do_translate(as, addr, xlat, plen, is_write, true, + &as); mr = section.mr; if (xen_enabled() && memory_access_is_direct(mr, is_write)) { From patchwork Fri Sep 15 08:40:20 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 814147 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3xtpls6KTqz9sPr for ; Fri, 15 Sep 2017 18:41:29 +1000 (AEST) Received: from localhost ([::1]:51953 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmBk-0006wK-03 for incoming@patchwork.ozlabs.org; Fri, 15 Sep 2017 04:41:28 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38146) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmB0-0006u0-Qc for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsmAx-0002Q7-IP for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:42 -0400 Received: from ozlabs.ru ([107.173.13.209]:44526) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmAx-0002Pl-4S for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:39 -0400 Received: from vpl1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id D40143A60051; Fri, 15 Sep 2017 04:41:51 -0400 (EDT) From: Alexey Kardashevskiy To: qemu-devel@nongnu.org Date: Fri, 15 Sep 2017 18:40:20 +1000 Message-Id: <20170915084030.40988-4-aik@ozlabs.ru> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170915084030.40988-1-aik@ozlabs.ru> References: <20170915084030.40988-1-aik@ozlabs.ru> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 107.173.13.209 Subject: [Qemu-devel] [PATCH qemu v2 03/13] memory: Open code FlatView rendering X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , Paolo Bonzini Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" We are going to share FlatView's between AddressSpace's and per-AS memory listeners won't suite the purpose anymore so open code the dispatch tree rendering. Signed-off-by: Alexey Kardashevskiy --- include/exec/memory-internal.h | 6 +++-- include/exec/memory.h | 1 - exec.c | 27 +++------------------ memory.c | 54 ++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 59 insertions(+), 29 deletions(-) diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index fb467acdba..9abde2f11c 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -22,8 +22,6 @@ #ifndef CONFIG_USER_ONLY typedef struct AddressSpaceDispatch AddressSpaceDispatch; -void address_space_init_dispatch(AddressSpace *as); -void address_space_unregister(AddressSpace *as); void address_space_destroy_dispatch(AddressSpace *as); extern const MemoryRegionOps unassigned_mem_ops; @@ -31,5 +29,9 @@ extern const MemoryRegionOps unassigned_mem_ops; bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr, unsigned size, bool is_write); +void mem_add(AddressSpace *as, MemoryRegionSection *section); +void mem_begin(AddressSpace *as); +void mem_commit(AddressSpace *as); + #endif #endif diff --git a/include/exec/memory.h b/include/exec/memory.h index 1dcd3122d7..9581f7a7db 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -318,7 +318,6 @@ struct AddressSpace { struct MemoryRegionIoeventfd *ioeventfds; struct AddressSpaceDispatch *dispatch; struct AddressSpaceDispatch *next_dispatch; - MemoryListener dispatch_listener; QTAILQ_HEAD(memory_listeners_as, MemoryListener) listeners; QTAILQ_ENTRY(AddressSpace) address_spaces_link; }; diff --git a/exec.c b/exec.c index bd94248390..3ed3718dea 100644 --- a/exec.c +++ b/exec.c @@ -1348,9 +1348,8 @@ static void register_multipage(AddressSpaceDispatch *d, phys_page_set(d, start_addr >> TARGET_PAGE_BITS, num_pages, section_index); } -static void mem_add(MemoryListener *listener, MemoryRegionSection *section) +void mem_add(AddressSpace *as, MemoryRegionSection *section) { - AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener); AddressSpaceDispatch *d = as->next_dispatch; MemoryRegionSection now = *section, remain = *section; Int128 page_size = int128_make64(TARGET_PAGE_SIZE); @@ -2674,9 +2673,8 @@ static void io_mem_init(void) NULL, UINT64_MAX); } -static void mem_begin(MemoryListener *listener) +void mem_begin(AddressSpace *as) { - AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener); AddressSpaceDispatch *d = g_new0(AddressSpaceDispatch, 1); uint16_t n; @@ -2700,9 +2698,8 @@ static void address_space_dispatch_free(AddressSpaceDispatch *d) g_free(d); } -static void mem_commit(MemoryListener *listener) +void mem_commit(AddressSpace *as) { - AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener); AddressSpaceDispatch *cur = as->dispatch; AddressSpaceDispatch *next = as->next_dispatch; @@ -2732,24 +2729,6 @@ static void tcg_commit(MemoryListener *listener) tlb_flush(cpuas->cpu); } -void address_space_init_dispatch(AddressSpace *as) -{ - as->dispatch = NULL; - as->dispatch_listener = (MemoryListener) { - .begin = mem_begin, - .commit = mem_commit, - .region_add = mem_add, - .region_nop = mem_add, - .priority = 0, - }; - memory_listener_register(&as->dispatch_listener, as); -} - -void address_space_unregister(AddressSpace *as) -{ - memory_listener_unregister(&as->dispatch_listener); -} - void address_space_destroy_dispatch(AddressSpace *as) { AddressSpaceDispatch *d = as->dispatch; diff --git a/memory.c b/memory.c index c0adc35410..62b0702d67 100644 --- a/memory.c +++ b/memory.c @@ -879,12 +879,63 @@ static void address_space_update_topology_pass(AddressSpace *as, } } +static void address_space_update_flatview(AddressSpace *as, + FlatView *old_view, + FlatView *new_view) +{ + unsigned iold, inew; + FlatRange *frold, *frnew; + + mem_begin(as); + /* + * FIXME: this is cut-n-paste from address_space_update_topology_pass, + * simplify it + */ + iold = inew = 0; + while (iold < old_view->nr || inew < new_view->nr) { + if (iold < old_view->nr) { + frold = &old_view->ranges[iold]; + } else { + frold = NULL; + } + if (inew < new_view->nr) { + frnew = &new_view->ranges[inew]; + } else { + frnew = NULL; + } + + if (frold + && (!frnew + || int128_lt(frold->addr.start, frnew->addr.start) + || (int128_eq(frold->addr.start, frnew->addr.start) + && !flatrange_equal(frold, frnew)))) { + ++iold; + } else if (frold && frnew && flatrange_equal(frold, frnew)) { + /* In both and unchanged (except logging may have changed) */ + MemoryRegionSection mrs = section_from_flat_range(frnew, as); + + mem_add(as, &mrs); + + ++iold; + ++inew; + } else { + /* In new */ + MemoryRegionSection mrs = section_from_flat_range(frnew, as); + + mem_add(as, &mrs); + + ++inew; + } + } + mem_commit(as); +} static void address_space_update_topology(AddressSpace *as) { FlatView *old_view = address_space_get_flatview(as); FlatView *new_view = generate_memory_topology(as->root); + address_space_update_flatview(as, old_view, new_view); address_space_update_topology_pass(as, old_view, new_view, false); address_space_update_topology_pass(as, old_view, new_view, true); @@ -2621,7 +2672,7 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name) QTAILQ_INIT(&as->listeners); QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link); as->name = g_strdup(name ? name : "anonymous"); - address_space_init_dispatch(as); + as->dispatch = NULL; memory_region_update_pending |= root->enabled; memory_region_transaction_commit(); } @@ -2672,7 +2723,6 @@ void address_space_destroy(AddressSpace *as) as->root = NULL; memory_region_transaction_commit(); QTAILQ_REMOVE(&address_spaces, as, address_spaces_link); - address_space_unregister(as); /* At this point, as->dispatch and as->current_map are dummy * entries that the guest should never use. Wait for the old From patchwork Fri Sep 15 08:40:21 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 814146 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3xtpls2cjXz9s3w for ; Fri, 15 Sep 2017 18:41:29 +1000 (AEST) Received: from localhost ([::1]:51952 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmBj-0006w4-CC for incoming@patchwork.ozlabs.org; Fri, 15 Sep 2017 04:41:27 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38147) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmB0-0006u1-R6 for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsmAy-0002QM-7t for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:42 -0400 Received: from ozlabs.ru ([107.173.13.209]:44552) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmAx-0002QD-Sf for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:40 -0400 Received: from vpl1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 2A1AA3A60055; Fri, 15 Sep 2017 04:41:52 -0400 (EDT) From: Alexey Kardashevskiy To: qemu-devel@nongnu.org Date: Fri, 15 Sep 2017 18:40:21 +1000 Message-Id: <20170915084030.40988-5-aik@ozlabs.ru> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170915084030.40988-1-aik@ozlabs.ru> References: <20170915084030.40988-1-aik@ozlabs.ru> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 107.173.13.209 Subject: [Qemu-devel] [PATCH qemu v2 04/13] memory: Move FlatView allocation to a helper X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , Paolo Bonzini Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This moves a FlatView allocation and initialization to a helper. While we are nere, replace g_new with g_new0 to not to bother if we add new fields in the future. Signed-off-by: Alexey Kardashevskiy --- memory.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/memory.c b/memory.c index 62b0702d67..a8381a8bc2 100644 --- a/memory.c +++ b/memory.c @@ -258,12 +258,14 @@ static bool flatrange_equal(FlatRange *a, FlatRange *b) && a->readonly == b->readonly; } -static void flatview_init(FlatView *view) +static FlatView *flatview_alloc(void) { + FlatView *view; + + view = g_new0(FlatView, 1); view->ref = 1; - view->ranges = NULL; - view->nr = 0; - view->nr_allocated = 0; + + return view; } /* Insert a range into a given position. Caller is responsible for maintaining @@ -706,8 +708,7 @@ static FlatView *generate_memory_topology(MemoryRegion *mr) { FlatView *view; - view = g_new(FlatView, 1); - flatview_init(view); + view = flatview_alloc(); if (mr) { render_memory_region(view, mr, int128_zero(), @@ -2665,8 +2666,7 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name) as->ref_count = 1; as->root = root; as->malloced = false; - as->current_map = g_new(FlatView, 1); - flatview_init(as->current_map); + as->current_map = flatview_alloc(); as->ioeventfd_nb = 0; as->ioeventfds = NULL; QTAILQ_INIT(&as->listeners); From patchwork Fri Sep 15 08:40:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 814161 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3xtpzS3pJcz9sPr for ; Fri, 15 Sep 2017 18:51:32 +1000 (AEST) Received: from localhost ([::1]:52000 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmLS-000132-Ip for incoming@patchwork.ozlabs.org; Fri, 15 Sep 2017 04:51:30 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38450) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmBV-0007LM-Ce for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:41:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsmBT-0002gt-Ok for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:41:13 -0400 Received: from ozlabs.ru ([107.173.13.209]:45038) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmBT-0002gc-AX for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:41:11 -0400 Received: from vpl1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 4F67F3A60057; Fri, 15 Sep 2017 04:41:54 -0400 (EDT) From: Alexey Kardashevskiy To: qemu-devel@nongnu.org Date: Fri, 15 Sep 2017 18:40:22 +1000 Message-Id: <20170915084030.40988-6-aik@ozlabs.ru> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170915084030.40988-1-aik@ozlabs.ru> References: <20170915084030.40988-1-aik@ozlabs.ru> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 107.173.13.209 Subject: [Qemu-devel] [PATCH qemu v2 05/13] memory: Move AddressSpaceDispatch from AddressSpace to FlatView X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , Paolo Bonzini Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" As we are going to share FlatView's between AddressSpace's, and AddressSpaceDispatch is a structure to perform quick lookup in FlatView, this moves ASD to FlatView. After previosly open coded ASD rendering, we can also remove as->next_dispatch as the new FlatView pointer is stored on a stack and set to an AS atomically. flatview_destroy() is executed under RCU instead of address_space_dispatch_free() now. This makes mem_begin/mem_commit to work with ASD and mem_add with FV as later on mem_add will be taking FV as an argument anyway. Signed-off-by: Alexey Kardashevskiy --- include/exec/memory-internal.h | 13 ++++++++----- include/exec/memory.h | 2 -- exec.c | 41 +++++++++++------------------------------ memory.c | 31 ++++++++++++++++++++++++------- 4 files changed, 43 insertions(+), 44 deletions(-) diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index 9abde2f11c..08b7e01047 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -21,17 +21,20 @@ #ifndef CONFIG_USER_ONLY typedef struct AddressSpaceDispatch AddressSpaceDispatch; - -void address_space_destroy_dispatch(AddressSpace *as); +typedef struct FlatView FlatView; extern const MemoryRegionOps unassigned_mem_ops; bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr, unsigned size, bool is_write); -void mem_add(AddressSpace *as, MemoryRegionSection *section); -void mem_begin(AddressSpace *as); -void mem_commit(AddressSpace *as); +void mem_add(AddressSpace *as, FlatView *fv, MemoryRegionSection *section); +AddressSpaceDispatch *mem_begin(AddressSpace *as); +void mem_commit(AddressSpaceDispatch *d); + +AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as); +AddressSpaceDispatch *flatview_to_dispatch(FlatView *fv); +void address_space_dispatch_free(AddressSpaceDispatch *d); #endif #endif diff --git a/include/exec/memory.h b/include/exec/memory.h index 9581f7a7db..2346f8b863 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -316,8 +316,6 @@ struct AddressSpace { int ioeventfd_nb; struct MemoryRegionIoeventfd *ioeventfds; - struct AddressSpaceDispatch *dispatch; - struct AddressSpaceDispatch *next_dispatch; QTAILQ_HEAD(memory_listeners_as, MemoryListener) listeners; QTAILQ_ENTRY(AddressSpace) address_spaces_link; }; diff --git a/exec.c b/exec.c index 3ed3718dea..6b0211bafc 100644 --- a/exec.c +++ b/exec.c @@ -188,8 +188,6 @@ typedef struct PhysPageMap { } PhysPageMap; struct AddressSpaceDispatch { - struct rcu_head rcu; - MemoryRegionSection *mru_section; /* This is a multi-level map on the physical address space. * The bottom level has pointers to MemoryRegionSections. @@ -486,7 +484,7 @@ static MemoryRegionSection address_space_do_translate(AddressSpace *as, IOMMUMemoryRegionClass *imrc; for (;;) { - AddressSpaceDispatch *d = atomic_rcu_read(&as->dispatch); + AddressSpaceDispatch *d = address_space_to_dispatch(as); section = address_space_translate_internal(d, addr, &addr, plen, is_mmio); iommu_mr = memory_region_get_iommu(section->mr); @@ -1223,7 +1221,7 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu, } else { AddressSpaceDispatch *d; - d = atomic_rcu_read(§ion->address_space->dispatch); + d = address_space_to_dispatch(section->address_space); iotlb = section - d->map.sections; iotlb += xlat; } @@ -1348,9 +1346,9 @@ static void register_multipage(AddressSpaceDispatch *d, phys_page_set(d, start_addr >> TARGET_PAGE_BITS, num_pages, section_index); } -void mem_add(AddressSpace *as, MemoryRegionSection *section) +void mem_add(AddressSpace *as, FlatView *fv, MemoryRegionSection *section) { - AddressSpaceDispatch *d = as->next_dispatch; + AddressSpaceDispatch *d = flatview_to_dispatch(fv); MemoryRegionSection now = *section, remain = *section; Int128 page_size = int128_make64(TARGET_PAGE_SIZE); @@ -2673,7 +2671,7 @@ static void io_mem_init(void) NULL, UINT64_MAX); } -void mem_begin(AddressSpace *as) +AddressSpaceDispatch *mem_begin(AddressSpace *as) { AddressSpaceDispatch *d = g_new0(AddressSpaceDispatch, 1); uint16_t n; @@ -2689,26 +2687,19 @@ void mem_begin(AddressSpace *as) d->phys_map = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .skip = 1 }; d->as = as; - as->next_dispatch = d; + + return d; } -static void address_space_dispatch_free(AddressSpaceDispatch *d) +void address_space_dispatch_free(AddressSpaceDispatch *d) { phys_sections_free(&d->map); g_free(d); } -void mem_commit(AddressSpace *as) +void mem_commit(AddressSpaceDispatch *d) { - AddressSpaceDispatch *cur = as->dispatch; - AddressSpaceDispatch *next = as->next_dispatch; - - phys_page_compact_all(next, next->map.nodes_nb); - - atomic_rcu_set(&as->dispatch, next); - if (cur) { - call_rcu(cur, address_space_dispatch_free, rcu); - } + phys_page_compact_all(d, d->map.nodes_nb); } static void tcg_commit(MemoryListener *listener) @@ -2724,21 +2715,11 @@ static void tcg_commit(MemoryListener *listener) * We reload the dispatch pointer now because cpu_reloading_memory_map() * may have split the RCU critical section. */ - d = atomic_rcu_read(&cpuas->as->dispatch); + d = address_space_to_dispatch(cpuas->as); atomic_rcu_set(&cpuas->memory_dispatch, d); tlb_flush(cpuas->cpu); } -void address_space_destroy_dispatch(AddressSpace *as) -{ - AddressSpaceDispatch *d = as->dispatch; - - atomic_rcu_set(&as->dispatch, NULL); - if (d) { - call_rcu(d, address_space_dispatch_free, rcu); - } -} - static void memory_map_init(void) { system_memory = g_malloc(sizeof(*system_memory)); diff --git a/memory.c b/memory.c index a8381a8bc2..1d93e4c836 100644 --- a/memory.c +++ b/memory.c @@ -229,6 +229,7 @@ struct FlatView { FlatRange *ranges; unsigned nr; unsigned nr_allocated; + struct AddressSpaceDispatch *dispatch; }; typedef struct AddressSpaceOps AddressSpaceOps; @@ -289,6 +290,9 @@ static void flatview_destroy(FlatView *view) { int i; + if (view->dispatch) { + address_space_dispatch_free(view->dispatch); + } for (i = 0; i < view->nr; i++) { memory_region_unref(view->ranges[i].mr); } @@ -304,10 +308,25 @@ static void flatview_ref(FlatView *view) static void flatview_unref(FlatView *view) { if (atomic_fetch_dec(&view->ref) == 1) { - flatview_destroy(view); + call_rcu(view, flatview_destroy, rcu); } } +static FlatView *address_space_to_flatview(AddressSpace *as) +{ + return atomic_rcu_read(&as->current_map); +} + +AddressSpaceDispatch *flatview_to_dispatch(FlatView *fv) +{ + return fv->dispatch; +} + +AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as) +{ + return flatview_to_dispatch(address_space_to_flatview(as)); +} + static bool can_merge(FlatRange *r1, FlatRange *r2) { return int128_eq(addrrange_end(r1->addr), r2->addr.start) @@ -887,7 +906,7 @@ static void address_space_update_flatview(AddressSpace *as, unsigned iold, inew; FlatRange *frold, *frnew; - mem_begin(as); + new_view->dispatch = mem_begin(as); /* * FIXME: this is cut-n-paste from address_space_update_topology_pass, * simplify it @@ -915,7 +934,7 @@ static void address_space_update_flatview(AddressSpace *as, /* In both and unchanged (except logging may have changed) */ MemoryRegionSection mrs = section_from_flat_range(frnew, as); - mem_add(as, &mrs); + mem_add(as, new_view, &mrs); ++iold; ++inew; @@ -923,12 +942,12 @@ static void address_space_update_flatview(AddressSpace *as, /* In new */ MemoryRegionSection mrs = section_from_flat_range(frnew, as); - mem_add(as, &mrs); + mem_add(as, new_view, &mrs); ++inew; } } - mem_commit(as); + mem_commit(new_view->dispatch); } static void address_space_update_topology(AddressSpace *as) @@ -2672,7 +2691,6 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name) QTAILQ_INIT(&as->listeners); QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link); as->name = g_strdup(name ? name : "anonymous"); - as->dispatch = NULL; memory_region_update_pending |= root->enabled; memory_region_transaction_commit(); } @@ -2681,7 +2699,6 @@ static void do_address_space_destroy(AddressSpace *as) { bool do_free = as->malloced; - address_space_destroy_dispatch(as); assert(QTAILQ_EMPTY(&as->listeners)); flatview_unref(as->current_map); From patchwork Fri Sep 15 08:40:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 814149 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3xtpmw2YfKz9sPr for ; Fri, 15 Sep 2017 18:42:24 +1000 (AEST) Received: from localhost ([::1]:51955 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmCc-0007uN-9x for incoming@patchwork.ozlabs.org; Fri, 15 Sep 2017 04:42:22 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38162) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmB1-0006uV-K8 for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsmB0-0002RE-Hr for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:43 -0400 Received: from ozlabs.ru ([107.173.13.209]:44668) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmB0-0002Ql-BY for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:42 -0400 Received: from vpl1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 99B4D3A60059; Fri, 15 Sep 2017 04:41:55 -0400 (EDT) From: Alexey Kardashevskiy To: qemu-devel@nongnu.org Date: Fri, 15 Sep 2017 18:40:23 +1000 Message-Id: <20170915084030.40988-7-aik@ozlabs.ru> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170915084030.40988-1-aik@ozlabs.ru> References: <20170915084030.40988-1-aik@ozlabs.ru> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 107.173.13.209 Subject: [Qemu-devel] [PATCH qemu v2 06/13] memory: Remove AddressSpace pointer from AddressSpaceDispatch X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , Paolo Bonzini Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" AS in ASD is only used to pass AS from mem_begin() to register_subpage() to store it in MemoryRegionSection, we can do this directly now. Signed-off-by: Alexey Kardashevskiy --- exec.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/exec.c b/exec.c index 6b0211bafc..3212c5e70d 100644 --- a/exec.c +++ b/exec.c @@ -194,7 +194,6 @@ struct AddressSpaceDispatch { */ PhysPageEntry phys_map; PhysPageMap map; - AddressSpace *as; }; #define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK) @@ -1304,7 +1303,8 @@ static void phys_sections_free(PhysPageMap *map) g_free(map->nodes); } -static void register_subpage(AddressSpaceDispatch *d, MemoryRegionSection *section) +static void register_subpage(AddressSpace *as, AddressSpaceDispatch *d, + MemoryRegionSection *section) { subpage_t *subpage; hwaddr base = section->offset_within_address_space @@ -1319,8 +1319,8 @@ static void register_subpage(AddressSpaceDispatch *d, MemoryRegionSection *secti assert(existing->mr->subpage || existing->mr == &io_mem_unassigned); if (!(existing->mr->subpage)) { - subpage = subpage_init(d->as, base); - subsection.address_space = d->as; + subpage = subpage_init(as, base); + subsection.address_space = as; subsection.mr = &subpage->iomem; phys_page_set(d, base >> TARGET_PAGE_BITS, 1, phys_section_add(&d->map, &subsection)); @@ -1357,7 +1357,7 @@ void mem_add(AddressSpace *as, FlatView *fv, MemoryRegionSection *section) - now.offset_within_address_space; now.size = int128_min(int128_make64(left), now.size); - register_subpage(d, &now); + register_subpage(as, d, &now); } else { now.size = int128_zero(); } @@ -1367,10 +1367,10 @@ void mem_add(AddressSpace *as, FlatView *fv, MemoryRegionSection *section) remain.offset_within_region += int128_get64(now.size); now = remain; if (int128_lt(remain.size, page_size)) { - register_subpage(d, &now); + register_subpage(as, d, &now); } else if (remain.offset_within_address_space & ~TARGET_PAGE_MASK) { now.size = page_size; - register_subpage(d, &now); + register_subpage(as, d, &now); } else { now.size = int128_and(now.size, int128_neg(page_size)); register_multipage(d, &now); @@ -2686,7 +2686,6 @@ AddressSpaceDispatch *mem_begin(AddressSpace *as) assert(n == PHYS_SECTION_WATCH); d->phys_map = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .skip = 1 }; - d->as = as; return d; } From patchwork Fri Sep 15 08:40:24 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 814159 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3xtpxr2G9hz9sPr for ; Fri, 15 Sep 2017 18:50:08 +1000 (AEST) Received: from localhost ([::1]:51990 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmK6-0008N2-Cp for incoming@patchwork.ozlabs.org; Fri, 15 Sep 2017 04:50:06 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38204) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmB5-0006xW-6i for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsmB1-0002Tg-Uz for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:47 -0400 Received: from ozlabs.ru ([107.173.13.209]:44668) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmB1-0002Ql-FC for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:43 -0400 Received: from vpl1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id BB9CF3A6005B; Fri, 15 Sep 2017 04:41:56 -0400 (EDT) From: Alexey Kardashevskiy To: qemu-devel@nongnu.org Date: Fri, 15 Sep 2017 18:40:24 +1000 Message-Id: <20170915084030.40988-8-aik@ozlabs.ru> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170915084030.40988-1-aik@ozlabs.ru> References: <20170915084030.40988-1-aik@ozlabs.ru> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 107.173.13.209 Subject: [Qemu-devel] [PATCH qemu v2 07/13] memory: Switch memory from using AddressSpace to FlatView X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , Paolo Bonzini Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" FlatView's will be shared between AddressSpace's and subpage_t and MemoryRegionSection cannot store AS anymore, hence this change. In particular, for: typedef struct subpage_t { MemoryRegion iomem; - AddressSpace *as; + FlatView *fv; hwaddr base; uint16_t sub_section[]; } subpage_t; struct MemoryRegionSection { MemoryRegion *mr; - AddressSpace *address_space; + FlatView *fv; hwaddr offset_within_region; Int128 size; hwaddr offset_within_address_space; bool readonly; }; Signed-off-by: Alexey Kardashevskiy --- include/exec/memory-internal.h | 2 +- include/exec/memory.h | 51 ++++++++---- exec.c | 180 ++++++++++++++++++++++++----------------- hw/intc/openpic_kvm.c | 2 +- memory.c | 32 ++++---- 5 files changed, 159 insertions(+), 108 deletions(-) diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index 08b7e01047..c8a5522510 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -28,7 +28,7 @@ extern const MemoryRegionOps unassigned_mem_ops; bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr, unsigned size, bool is_write); -void mem_add(AddressSpace *as, FlatView *fv, MemoryRegionSection *section); +void mem_add(FlatView *fv, MemoryRegionSection *section); AddressSpaceDispatch *mem_begin(AddressSpace *as); void mem_commit(AddressSpaceDispatch *d); diff --git a/include/exec/memory.h b/include/exec/memory.h index 2346f8b863..7816e5d655 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -48,6 +48,7 @@ typedef struct MemoryRegionOps MemoryRegionOps; typedef struct MemoryRegionMmio MemoryRegionMmio; +typedef struct FlatView FlatView; struct MemoryRegionMmio { CPUReadMemoryFunc *read[3]; @@ -320,6 +321,8 @@ struct AddressSpace { QTAILQ_ENTRY(AddressSpace) address_spaces_link; }; +FlatView *address_space_to_flatview(AddressSpace *as); + /** * MemoryRegionSection: describes a fragment of a #MemoryRegion * @@ -333,7 +336,7 @@ struct AddressSpace { */ struct MemoryRegionSection { MemoryRegion *mr; - AddressSpace *address_space; + FlatView *fv; hwaddr offset_within_region; Int128 size; hwaddr offset_within_address_space; @@ -1842,9 +1845,17 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr, * @len: pointer to length * @is_write: indicates the transfer direction */ -MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, - hwaddr *xlat, hwaddr *len, - bool is_write); +MemoryRegion *flatview_translate(FlatView *fv, + hwaddr addr, hwaddr *xlat, + hwaddr *len, bool is_write); + +static inline MemoryRegion *address_space_translate(AddressSpace *as, + hwaddr addr, hwaddr *xlat, + hwaddr *len, bool is_write) +{ + return flatview_translate(address_space_to_flatview(as), + addr, xlat, len, is_write); +} /* address_space_access_valid: check for validity of accessing an address * space range @@ -1895,12 +1906,13 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len, /* Internal functions, part of the implementation of address_space_read. */ -MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, uint8_t *buf, - int len, hwaddr addr1, hwaddr l, - MemoryRegion *mr); -MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, uint8_t *buf, int len); +MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr, + MemTxAttrs attrs, uint8_t *buf, + int len, hwaddr addr1, hwaddr l, + MemoryRegion *mr); + +MemTxResult flatview_read_full(FlatView *fv, hwaddr addr, + MemTxAttrs attrs, uint8_t *buf, int len); void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr); static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write) @@ -1927,8 +1939,8 @@ static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write) * @buf: buffer with the data transferred */ static inline __attribute__((__always_inline__)) -MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, - uint8_t *buf, int len) +MemTxResult flatview_read(FlatView *fv, hwaddr addr, MemTxAttrs attrs, + uint8_t *buf, int len) { MemTxResult result = MEMTX_OK; hwaddr l, addr1; @@ -1939,22 +1951,29 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, if (len) { rcu_read_lock(); l = len; - mr = address_space_translate(as, addr, &addr1, &l, false); + mr = flatview_translate(fv, addr, &addr1, &l, false); if (len == l && memory_access_is_direct(mr, false)) { ptr = qemu_map_ram_ptr(mr->ram_block, addr1); memcpy(buf, ptr, len); } else { - result = address_space_read_continue(as, addr, attrs, buf, len, - addr1, l, mr); + result = flatview_read_continue(fv, addr, attrs, buf, len, + addr1, l, mr); } rcu_read_unlock(); } } else { - result = address_space_read_full(as, addr, attrs, buf, len); + result = flatview_read_full(fv, addr, attrs, buf, len); } return result; } +static inline MemTxResult address_space_read(AddressSpace *as, hwaddr addr, + MemTxAttrs attrs, uint8_t *buf, + int len) +{ + return flatview_read(address_space_to_flatview(as), addr, attrs, buf, len); +} + /** * address_space_read_cached: read from a cached RAM region * diff --git a/exec.c b/exec.c index 3212c5e70d..b561098df3 100644 --- a/exec.c +++ b/exec.c @@ -199,7 +199,7 @@ struct AddressSpaceDispatch { #define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK) typedef struct subpage_t { MemoryRegion iomem; - AddressSpace *as; + FlatView *fv; hwaddr base; uint16_t sub_section[]; } subpage_t; @@ -469,13 +469,13 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x } /* Called from RCU critical section */ -static MemoryRegionSection address_space_do_translate(AddressSpace *as, - hwaddr addr, - hwaddr *xlat, - hwaddr *plen, - bool is_write, - bool is_mmio, - AddressSpace **target_as) +static MemoryRegionSection flatview_do_translate(FlatView *fv, + hwaddr addr, + hwaddr *xlat, + hwaddr *plen, + bool is_write, + bool is_mmio, + AddressSpace **target_as) { IOMMUTLBEntry iotlb; MemoryRegionSection *section; @@ -483,8 +483,9 @@ static MemoryRegionSection address_space_do_translate(AddressSpace *as, IOMMUMemoryRegionClass *imrc; for (;;) { - AddressSpaceDispatch *d = address_space_to_dispatch(as); - section = address_space_translate_internal(d, addr, &addr, plen, is_mmio); + section = address_space_translate_internal( + flatview_to_dispatch(fv), addr, &addr, + plen, is_mmio); iommu_mr = memory_region_get_iommu(section->mr); if (!iommu_mr) { @@ -501,7 +502,7 @@ static MemoryRegionSection address_space_do_translate(AddressSpace *as, goto translate_fail; } - as = iotlb.target_as; + fv = address_space_to_flatview(iotlb.target_as); *target_as = iotlb.target_as; } @@ -524,8 +525,8 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr, plen = (hwaddr)-1; /* This can never be MMIO. */ - section = address_space_do_translate(as, addr, &xlat, &plen, - is_write, false, &as); + section = flatview_do_translate(address_space_to_flatview(as), addr, + &xlat, &plen, is_write, false, &as); /* Illegal translation */ if (section.mr == &io_mem_unassigned) { @@ -561,16 +562,15 @@ iotlb_fail: } /* Called from RCU critical section */ -MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, - hwaddr *xlat, hwaddr *plen, - bool is_write) +MemoryRegion *flatview_translate(FlatView *fv, hwaddr addr, hwaddr *xlat, + hwaddr *plen, bool is_write) { MemoryRegion *mr; MemoryRegionSection section; + AddressSpace *as = NULL; /* This can be MMIO, so setup MMIO bit. */ - section = address_space_do_translate(as, addr, xlat, plen, is_write, true, - &as); + section = flatview_do_translate(fv, addr, xlat, plen, is_write, true, &as); mr = section.mr; if (xen_enabled() && memory_access_is_direct(mr, is_write)) { @@ -1220,7 +1220,7 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu, } else { AddressSpaceDispatch *d; - d = address_space_to_dispatch(section->address_space); + d = flatview_to_dispatch(section->fv); iotlb = section - d->map.sections; iotlb += xlat; } @@ -1246,7 +1246,7 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu, static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, uint16_t section); -static subpage_t *subpage_init(AddressSpace *as, hwaddr base); +static subpage_t *subpage_init(FlatView *fv, hwaddr base); static void *(*phys_mem_alloc)(size_t size, uint64_t *align) = qemu_anon_ram_alloc; @@ -1303,7 +1303,7 @@ static void phys_sections_free(PhysPageMap *map) g_free(map->nodes); } -static void register_subpage(AddressSpace *as, AddressSpaceDispatch *d, +static void register_subpage(FlatView *fv, AddressSpaceDispatch *d, MemoryRegionSection *section) { subpage_t *subpage; @@ -1319,8 +1319,8 @@ static void register_subpage(AddressSpace *as, AddressSpaceDispatch *d, assert(existing->mr->subpage || existing->mr == &io_mem_unassigned); if (!(existing->mr->subpage)) { - subpage = subpage_init(as, base); - subsection.address_space = as; + subpage = subpage_init(fv, base); + subsection.fv = fv; subsection.mr = &subpage->iomem; phys_page_set(d, base >> TARGET_PAGE_BITS, 1, phys_section_add(&d->map, &subsection)); @@ -1346,7 +1346,7 @@ static void register_multipage(AddressSpaceDispatch *d, phys_page_set(d, start_addr >> TARGET_PAGE_BITS, num_pages, section_index); } -void mem_add(AddressSpace *as, FlatView *fv, MemoryRegionSection *section) +void mem_add(FlatView *fv, MemoryRegionSection *section) { AddressSpaceDispatch *d = flatview_to_dispatch(fv); MemoryRegionSection now = *section, remain = *section; @@ -1357,7 +1357,7 @@ void mem_add(AddressSpace *as, FlatView *fv, MemoryRegionSection *section) - now.offset_within_address_space; now.size = int128_min(int128_make64(left), now.size); - register_subpage(as, d, &now); + register_subpage(fv, d, &now); } else { now.size = int128_zero(); } @@ -1367,10 +1367,10 @@ void mem_add(AddressSpace *as, FlatView *fv, MemoryRegionSection *section) remain.offset_within_region += int128_get64(now.size); now = remain; if (int128_lt(remain.size, page_size)) { - register_subpage(as, d, &now); + register_subpage(fv, d, &now); } else if (remain.offset_within_address_space & ~TARGET_PAGE_MASK) { now.size = page_size; - register_subpage(as, d, &now); + register_subpage(fv, d, &now); } else { now.size = int128_and(now.size, int128_neg(page_size)); register_multipage(d, &now); @@ -2501,6 +2501,11 @@ static const MemoryRegionOps watch_mem_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; +static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs, + const uint8_t *buf, int len); +static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len, + bool is_write); + static MemTxResult subpage_read(void *opaque, hwaddr addr, uint64_t *data, unsigned len, MemTxAttrs attrs) { @@ -2512,8 +2517,7 @@ static MemTxResult subpage_read(void *opaque, hwaddr addr, uint64_t *data, printf("%s: subpage %p len %u addr " TARGET_FMT_plx "\n", __func__, subpage, len, addr); #endif - res = address_space_read(subpage->as, addr + subpage->base, - attrs, buf, len); + res = flatview_read(subpage->fv, addr + subpage->base, attrs, buf, len); if (res) { return res; } @@ -2562,8 +2566,7 @@ static MemTxResult subpage_write(void *opaque, hwaddr addr, default: abort(); } - return address_space_write(subpage->as, addr + subpage->base, - attrs, buf, len); + return flatview_write(subpage->fv, addr + subpage->base, attrs, buf, len); } static bool subpage_accepts(void *opaque, hwaddr addr, @@ -2575,8 +2578,8 @@ static bool subpage_accepts(void *opaque, hwaddr addr, __func__, subpage, is_write ? 'w' : 'r', len, addr); #endif - return address_space_access_valid(subpage->as, addr + subpage->base, - len, is_write); + return flatview_access_valid(subpage->fv, addr + subpage->base, + len, is_write); } static const MemoryRegionOps subpage_ops = { @@ -2610,12 +2613,12 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, return 0; } -static subpage_t *subpage_init(AddressSpace *as, hwaddr base) +static subpage_t *subpage_init(FlatView *fv, hwaddr base) { subpage_t *mmio; mmio = g_malloc0(sizeof(subpage_t) + TARGET_PAGE_SIZE * sizeof(uint16_t)); - mmio->as = as; + mmio->fv = fv; mmio->base = base; memory_region_init_io(&mmio->iomem, NULL, &subpage_ops, mmio, NULL, TARGET_PAGE_SIZE); @@ -2629,12 +2632,11 @@ static subpage_t *subpage_init(AddressSpace *as, hwaddr base) return mmio; } -static uint16_t dummy_section(PhysPageMap *map, AddressSpace *as, - MemoryRegion *mr) +static uint16_t dummy_section(PhysPageMap *map, FlatView *fv, MemoryRegion *mr) { - assert(as); + assert(fv); MemoryRegionSection section = { - .address_space = as, + .fv = fv, .mr = mr, .offset_within_address_space = 0, .offset_within_region = 0, @@ -2673,16 +2675,17 @@ static void io_mem_init(void) AddressSpaceDispatch *mem_begin(AddressSpace *as) { + FlatView *fv = address_space_to_flatview(as); AddressSpaceDispatch *d = g_new0(AddressSpaceDispatch, 1); uint16_t n; - n = dummy_section(&d->map, as, &io_mem_unassigned); + n = dummy_section(&d->map, fv, &io_mem_unassigned); assert(n == PHYS_SECTION_UNASSIGNED); - n = dummy_section(&d->map, as, &io_mem_notdirty); + n = dummy_section(&d->map, fv, &io_mem_notdirty); assert(n == PHYS_SECTION_NOTDIRTY); - n = dummy_section(&d->map, as, &io_mem_rom); + n = dummy_section(&d->map, fv, &io_mem_rom); assert(n == PHYS_SECTION_ROM); - n = dummy_section(&d->map, as, &io_mem_watch); + n = dummy_section(&d->map, fv, &io_mem_watch); assert(n == PHYS_SECTION_WATCH); d->phys_map = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .skip = 1 }; @@ -2862,11 +2865,11 @@ static bool prepare_mmio_access(MemoryRegion *mr) } /* Called within RCU critical section. */ -static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, - const uint8_t *buf, - int len, hwaddr addr1, - hwaddr l, MemoryRegion *mr) +static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr, + MemTxAttrs attrs, + const uint8_t *buf, + int len, hwaddr addr1, + hwaddr l, MemoryRegion *mr) { uint8_t *ptr; uint64_t val; @@ -2928,14 +2931,14 @@ static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr, } l = len; - mr = address_space_translate(as, addr, &addr1, &l, true); + mr = flatview_translate(fv, addr, &addr1, &l, true); } return result; } -MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, - const uint8_t *buf, int len) +static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs, + const uint8_t *buf, int len) { hwaddr l; hwaddr addr1; @@ -2945,20 +2948,27 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, if (len > 0) { rcu_read_lock(); l = len; - mr = address_space_translate(as, addr, &addr1, &l, true); - result = address_space_write_continue(as, addr, attrs, buf, len, - addr1, l, mr); + mr = flatview_translate(fv, addr, &addr1, &l, true); + result = flatview_write_continue(fv, addr, attrs, buf, len, + addr1, l, mr); rcu_read_unlock(); } return result; } +MemTxResult address_space_write(AddressSpace *as, hwaddr addr, + MemTxAttrs attrs, + const uint8_t *buf, int len) +{ + return flatview_write(address_space_to_flatview(as), addr, attrs, buf, len); +} + /* Called within RCU critical section. */ -MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, uint8_t *buf, - int len, hwaddr addr1, hwaddr l, - MemoryRegion *mr) +MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr, + MemTxAttrs attrs, uint8_t *buf, + int len, hwaddr addr1, hwaddr l, + MemoryRegion *mr) { uint8_t *ptr; uint64_t val; @@ -3018,14 +3028,14 @@ MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr, } l = len; - mr = address_space_translate(as, addr, &addr1, &l, false); + mr = flatview_translate(fv, addr, &addr1, &l, false); } return result; } -MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, uint8_t *buf, int len) +MemTxResult flatview_read_full(FlatView *fv, hwaddr addr, + MemTxAttrs attrs, uint8_t *buf, int len) { hwaddr l; hwaddr addr1; @@ -3035,25 +3045,33 @@ MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr, if (len > 0) { rcu_read_lock(); l = len; - mr = address_space_translate(as, addr, &addr1, &l, false); - result = address_space_read_continue(as, addr, attrs, buf, len, - addr1, l, mr); + mr = flatview_translate(fv, addr, &addr1, &l, false); + result = flatview_read_continue(fv, addr, attrs, buf, len, + addr1, l, mr); rcu_read_unlock(); } return result; } -MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, - uint8_t *buf, int len, bool is_write) +static MemTxResult flatview_rw(FlatView *fv, hwaddr addr, MemTxAttrs attrs, + uint8_t *buf, int len, bool is_write) { if (is_write) { - return address_space_write(as, addr, attrs, (uint8_t *)buf, len); + return flatview_write(fv, addr, attrs, (uint8_t *)buf, len); } else { - return address_space_read(as, addr, attrs, (uint8_t *)buf, len); + return flatview_read(fv, addr, attrs, (uint8_t *)buf, len); } } +MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, + MemTxAttrs attrs, uint8_t *buf, + int len, bool is_write) +{ + return flatview_rw(address_space_to_flatview(as), + addr, attrs, buf, len, is_write); +} + void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf, int len, int is_write) { @@ -3211,7 +3229,8 @@ static void cpu_notify_map_clients(void) qemu_mutex_unlock(&map_client_list_lock); } -bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write) +static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len, + bool is_write) { MemoryRegion *mr; hwaddr l, xlat; @@ -3219,7 +3238,7 @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_ rcu_read_lock(); while (len > 0) { l = len; - mr = address_space_translate(as, addr, &xlat, &l, is_write); + mr = flatview_translate(fv, addr, &xlat, &l, is_write); if (!memory_access_is_direct(mr, is_write)) { l = memory_access_size(mr, l, addr); if (!memory_region_access_valid(mr, xlat, l, is_write)) { @@ -3235,8 +3254,16 @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_ return true; } +bool address_space_access_valid(AddressSpace *as, hwaddr addr, + int len, bool is_write) +{ + return flatview_access_valid(address_space_to_flatview(as), + addr, len, is_write); +} + static hwaddr -address_space_extend_translation(AddressSpace *as, hwaddr addr, hwaddr target_len, +flatview_extend_translation(FlatView *fv, hwaddr addr, + hwaddr target_len, MemoryRegion *mr, hwaddr base, hwaddr len, bool is_write) { @@ -3253,7 +3280,8 @@ address_space_extend_translation(AddressSpace *as, hwaddr addr, hwaddr target_le } len = target_len; - this_mr = address_space_translate(as, addr, &xlat, &len, is_write); + this_mr = flatview_translate(fv, addr, &xlat, + &len, is_write); if (this_mr != mr || xlat != base + done) { return done; } @@ -3276,6 +3304,7 @@ void *address_space_map(AddressSpace *as, hwaddr l, xlat; MemoryRegion *mr; void *ptr; + FlatView *fv = address_space_to_flatview(as); if (len == 0) { return NULL; @@ -3283,7 +3312,7 @@ void *address_space_map(AddressSpace *as, l = len; rcu_read_lock(); - mr = address_space_translate(as, addr, &xlat, &l, is_write); + mr = flatview_translate(fv, addr, &xlat, &l, is_write); if (!memory_access_is_direct(mr, is_write)) { if (atomic_xchg(&bounce.in_use, true)) { @@ -3299,7 +3328,7 @@ void *address_space_map(AddressSpace *as, memory_region_ref(mr); bounce.mr = mr; if (!is_write) { - address_space_read(as, addr, MEMTXATTRS_UNSPECIFIED, + flatview_read(fv, addr, MEMTXATTRS_UNSPECIFIED, bounce.buffer, l); } @@ -3310,7 +3339,8 @@ void *address_space_map(AddressSpace *as, memory_region_ref(mr); - *plen = address_space_extend_translation(as, addr, len, mr, xlat, l, is_write); + *plen = flatview_extend_translation(fv, addr, len, mr, xlat, + l, is_write); ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true); rcu_read_unlock(); diff --git a/hw/intc/openpic_kvm.c b/hw/intc/openpic_kvm.c index 0518e017c4..fa83420254 100644 --- a/hw/intc/openpic_kvm.c +++ b/hw/intc/openpic_kvm.c @@ -124,7 +124,7 @@ static void kvm_openpic_region_add(MemoryListener *listener, uint64_t reg_base; int ret; - if (section->address_space != &address_space_memory) { + if (section->fv != address_space_to_flatview(&address_space_memory)) { abort(); } diff --git a/memory.c b/memory.c index 1d93e4c836..0f51445d30 100644 --- a/memory.c +++ b/memory.c @@ -154,7 +154,8 @@ enum ListenerDirection { Forward, Reverse }; /* No need to ref/unref .mr, the FlatRange keeps it alive. */ #define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback, _args...) \ do { \ - MemoryRegionSection mrs = section_from_flat_range(fr, as); \ + MemoryRegionSection mrs = section_from_flat_range(fr, \ + address_space_to_flatview(as)); \ MEMORY_LISTENER_CALL(as, callback, dir, &mrs, ##_args); \ } while(0) @@ -238,11 +239,11 @@ typedef struct AddressSpaceOps AddressSpaceOps; for (var = (view)->ranges; var < (view)->ranges + (view)->nr; ++var) static inline MemoryRegionSection -section_from_flat_range(FlatRange *fr, AddressSpace *as) +section_from_flat_range(FlatRange *fr, FlatView *fv) { return (MemoryRegionSection) { .mr = fr->mr, - .address_space = as, + .fv = fv, .offset_within_region = fr->offset_in_region, .size = fr->addr.size, .offset_within_address_space = int128_get64(fr->addr.start), @@ -312,7 +313,7 @@ static void flatview_unref(FlatView *view) } } -static FlatView *address_space_to_flatview(AddressSpace *as) +FlatView *address_space_to_flatview(AddressSpace *as) { return atomic_rcu_read(&as->current_map); } @@ -760,7 +761,7 @@ static void address_space_add_del_ioeventfds(AddressSpace *as, fds_new[inew]))) { fd = &fds_old[iold]; section = (MemoryRegionSection) { - .address_space = as, + .fv = address_space_to_flatview(as), .offset_within_address_space = int128_get64(fd->addr.start), .size = fd->addr.size, }; @@ -773,7 +774,7 @@ static void address_space_add_del_ioeventfds(AddressSpace *as, fds_old[iold]))) { fd = &fds_new[inew]; section = (MemoryRegionSection) { - .address_space = as, + .fv = address_space_to_flatview(as), .offset_within_address_space = int128_get64(fd->addr.start), .size = fd->addr.size, }; @@ -932,17 +933,17 @@ static void address_space_update_flatview(AddressSpace *as, ++iold; } else if (frold && frnew && flatrange_equal(frold, frnew)) { /* In both and unchanged (except logging may have changed) */ - MemoryRegionSection mrs = section_from_flat_range(frnew, as); + MemoryRegionSection mrs = section_from_flat_range(frnew, new_view); - mem_add(as, new_view, &mrs); + mem_add(new_view, &mrs); ++iold; ++inew; } else { /* In new */ - MemoryRegionSection mrs = section_from_flat_range(frnew, as); + MemoryRegionSection mrs = section_from_flat_range(frnew, new_view); - mem_add(as, new_view, &mrs); + mem_add(new_view, &mrs); ++inew; } @@ -1906,7 +1907,7 @@ void memory_region_sync_dirty_bitmap(MemoryRegion *mr) view = address_space_get_flatview(as); FOR_EACH_FLAT_RANGE(fr, view) { if (fr->mr == mr) { - MemoryRegionSection mrs = section_from_flat_range(fr, as); + MemoryRegionSection mrs = section_from_flat_range(fr, view); listener->log_sync(listener, &mrs); } } @@ -2009,7 +2010,7 @@ static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpa FOR_EACH_FLAT_RANGE(fr, view) { if (fr->mr == mr) { section = (MemoryRegionSection) { - .address_space = as, + .fv = view, .offset_within_address_space = int128_get64(fr->addr.start), .size = fr->addr.size, }; @@ -2371,7 +2372,7 @@ static MemoryRegionSection memory_region_find_rcu(MemoryRegion *mr, } ret.mr = fr->mr; - ret.address_space = as; + ret.fv = view; range = addrrange_intersection(range, fr->addr); ret.offset_within_region = fr->offset_in_region; ret.offset_within_region += int128_get64(int128_sub(range.start, @@ -2420,7 +2421,8 @@ void memory_global_dirty_log_sync(void) view = address_space_get_flatview(as); FOR_EACH_FLAT_RANGE(fr, view) { if (fr->dirty_log_mask) { - MemoryRegionSection mrs = section_from_flat_range(fr, as); + MemoryRegionSection mrs = section_from_flat_range(fr, view); + listener->log_sync(listener, &mrs); } } @@ -2505,7 +2507,7 @@ static void listener_add_address_space(MemoryListener *listener, FOR_EACH_FLAT_RANGE(fr, view) { MemoryRegionSection section = { .mr = fr->mr, - .address_space = as, + .fv = view, .offset_within_region = fr->offset_in_region, .size = fr->addr.size, .offset_within_address_space = int128_get64(fr->addr.start), From patchwork Fri Sep 15 08:40:25 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 814148 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3xtplv64znz9s3w for ; Fri, 15 Sep 2017 18:41:31 +1000 (AEST) Received: from localhost ([::1]:51954 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmBl-0006yf-PC for incoming@patchwork.ozlabs.org; Fri, 15 Sep 2017 04:41:29 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38181) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmB3-0006wG-PI for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsmB2-0002UW-QW for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:45 -0400 Received: from ozlabs.ru ([107.173.13.209]:44668) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmB2-0002Ql-JS for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:44 -0400 Received: from vpl1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 11C623A6005D; Fri, 15 Sep 2017 04:41:57 -0400 (EDT) From: Alexey Kardashevskiy To: qemu-devel@nongnu.org Date: Fri, 15 Sep 2017 18:40:25 +1000 Message-Id: <20170915084030.40988-9-aik@ozlabs.ru> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170915084030.40988-1-aik@ozlabs.ru> References: <20170915084030.40988-1-aik@ozlabs.ru> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 107.173.13.209 Subject: [Qemu-devel] [PATCH qemu v2 08/13] memory: Cleanup after switching to FlatView X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , Paolo Bonzini Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" We store AddressSpaceDispatch* in FlatView anyway so there is no need to carry it from mem_add() to register_subpage/register_multipage. Signed-off-by: Alexey Kardashevskiy --- exec.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/exec.c b/exec.c index b561098df3..3e02b82c05 100644 --- a/exec.c +++ b/exec.c @@ -1303,9 +1303,9 @@ static void phys_sections_free(PhysPageMap *map) g_free(map->nodes); } -static void register_subpage(FlatView *fv, AddressSpaceDispatch *d, - MemoryRegionSection *section) +static void register_subpage(FlatView *fv, MemoryRegionSection *section) { + AddressSpaceDispatch *d = flatview_to_dispatch(fv); subpage_t *subpage; hwaddr base = section->offset_within_address_space & TARGET_PAGE_MASK; @@ -1334,9 +1334,10 @@ static void register_subpage(FlatView *fv, AddressSpaceDispatch *d, } -static void register_multipage(AddressSpaceDispatch *d, +static void register_multipage(FlatView *fv, MemoryRegionSection *section) { + AddressSpaceDispatch *d = flatview_to_dispatch(fv); hwaddr start_addr = section->offset_within_address_space; uint16_t section_index = phys_section_add(&d->map, section); uint64_t num_pages = int128_get64(int128_rshift(section->size, @@ -1348,7 +1349,6 @@ static void register_multipage(AddressSpaceDispatch *d, void mem_add(FlatView *fv, MemoryRegionSection *section) { - AddressSpaceDispatch *d = flatview_to_dispatch(fv); MemoryRegionSection now = *section, remain = *section; Int128 page_size = int128_make64(TARGET_PAGE_SIZE); @@ -1357,7 +1357,7 @@ void mem_add(FlatView *fv, MemoryRegionSection *section) - now.offset_within_address_space; now.size = int128_min(int128_make64(left), now.size); - register_subpage(fv, d, &now); + register_subpage(fv, &now); } else { now.size = int128_zero(); } @@ -1367,13 +1367,13 @@ void mem_add(FlatView *fv, MemoryRegionSection *section) remain.offset_within_region += int128_get64(now.size); now = remain; if (int128_lt(remain.size, page_size)) { - register_subpage(fv, d, &now); + register_subpage(fv, &now); } else if (remain.offset_within_address_space & ~TARGET_PAGE_MASK) { now.size = page_size; - register_subpage(fv, d, &now); + register_subpage(fv, &now); } else { now.size = int128_and(now.size, int128_neg(page_size)); - register_multipage(d, &now); + register_multipage(fv, &now); } } } From patchwork Fri Sep 15 08:40:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 814150 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3xtppk6lhYz9s3w for ; Fri, 15 Sep 2017 18:43:58 +1000 (AEST) Received: from localhost ([::1]:51961 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmE9-0001w9-0b for incoming@patchwork.ozlabs.org; Fri, 15 Sep 2017 04:43:57 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38203) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmB5-0006xU-6F for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsmB4-0002WM-10 for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:47 -0400 Received: from ozlabs.ru ([107.173.13.209]:44668) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmB3-0002Ql-NT for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:45 -0400 Received: from vpl1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 303113A6005F; Fri, 15 Sep 2017 04:41:59 -0400 (EDT) From: Alexey Kardashevskiy To: qemu-devel@nongnu.org Date: Fri, 15 Sep 2017 18:40:26 +1000 Message-Id: <20170915084030.40988-10-aik@ozlabs.ru> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170915084030.40988-1-aik@ozlabs.ru> References: <20170915084030.40988-1-aik@ozlabs.ru> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 107.173.13.209 Subject: [Qemu-devel] [PATCH qemu v2 09/13] memory: Rename mem_begin/mem_commit/mem_add helpers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , Paolo Bonzini Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This renames some helper to reflect better what they do. This drops AS in address_space_update_flatview() as it is not used anymore and renames to flatview_render_new(). Signed-off-by: Alexey Kardashevskiy --- include/exec/memory-internal.h | 6 +++--- exec.c | 7 +++---- memory.c | 14 ++++++-------- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index c8a5522510..e87a30fcae 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -28,9 +28,9 @@ extern const MemoryRegionOps unassigned_mem_ops; bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr, unsigned size, bool is_write); -void mem_add(FlatView *fv, MemoryRegionSection *section); -AddressSpaceDispatch *mem_begin(AddressSpace *as); -void mem_commit(AddressSpaceDispatch *d); +void flatview_mem_add(FlatView *fv, MemoryRegionSection *section); +AddressSpaceDispatch *address_space_dispatch_alloc(FlatView *fv); +void address_space_dispatch_compact(AddressSpaceDispatch *d); AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as); AddressSpaceDispatch *flatview_to_dispatch(FlatView *fv); diff --git a/exec.c b/exec.c index 3e02b82c05..11e0e3c927 100644 --- a/exec.c +++ b/exec.c @@ -1347,7 +1347,7 @@ static void register_multipage(FlatView *fv, phys_page_set(d, start_addr >> TARGET_PAGE_BITS, num_pages, section_index); } -void mem_add(FlatView *fv, MemoryRegionSection *section) +void flatview_mem_add(FlatView *fv, MemoryRegionSection *section) { MemoryRegionSection now = *section, remain = *section; Int128 page_size = int128_make64(TARGET_PAGE_SIZE); @@ -2673,9 +2673,8 @@ static void io_mem_init(void) NULL, UINT64_MAX); } -AddressSpaceDispatch *mem_begin(AddressSpace *as) +AddressSpaceDispatch *address_space_dispatch_alloc(FlatView *fv) { - FlatView *fv = address_space_to_flatview(as); AddressSpaceDispatch *d = g_new0(AddressSpaceDispatch, 1); uint16_t n; @@ -2699,7 +2698,7 @@ void address_space_dispatch_free(AddressSpaceDispatch *d) g_free(d); } -void mem_commit(AddressSpaceDispatch *d) +void address_space_dispatch_compact(AddressSpaceDispatch *d) { phys_page_compact_all(d, d->map.nodes_nb); } diff --git a/memory.c b/memory.c index 0f51445d30..0651be49ac 100644 --- a/memory.c +++ b/memory.c @@ -900,14 +900,12 @@ static void address_space_update_topology_pass(AddressSpace *as, } } -static void address_space_update_flatview(AddressSpace *as, - FlatView *old_view, - FlatView *new_view) +static void flatview_render_new(FlatView *old_view, FlatView *new_view) { unsigned iold, inew; FlatRange *frold, *frnew; - new_view->dispatch = mem_begin(as); + new_view->dispatch = address_space_dispatch_alloc(new_view); /* * FIXME: this is cut-n-paste from address_space_update_topology_pass, * simplify it @@ -935,7 +933,7 @@ static void address_space_update_flatview(AddressSpace *as, /* In both and unchanged (except logging may have changed) */ MemoryRegionSection mrs = section_from_flat_range(frnew, new_view); - mem_add(new_view, &mrs); + flatview_mem_add(new_view, &mrs); ++iold; ++inew; @@ -943,12 +941,12 @@ static void address_space_update_flatview(AddressSpace *as, /* In new */ MemoryRegionSection mrs = section_from_flat_range(frnew, new_view); - mem_add(new_view, &mrs); + flatview_mem_add(new_view, &mrs); ++inew; } } - mem_commit(new_view->dispatch); + address_space_dispatch_compact(new_view->dispatch); } static void address_space_update_topology(AddressSpace *as) @@ -956,7 +954,7 @@ static void address_space_update_topology(AddressSpace *as) FlatView *old_view = address_space_get_flatview(as); FlatView *new_view = generate_memory_topology(as->root); - address_space_update_flatview(as, old_view, new_view); + flatview_render_new(old_view, new_view); address_space_update_topology_pass(as, old_view, new_view, false); address_space_update_topology_pass(as, old_view, new_view, true); From patchwork Fri Sep 15 08:40:27 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 814153 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3xtpqp0gYjz9s3w for ; Fri, 15 Sep 2017 18:44:53 +1000 (AEST) Received: from localhost ([::1]:51964 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmF1-0002jj-DC for incoming@patchwork.ozlabs.org; Fri, 15 Sep 2017 04:44:51 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38217) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmB6-0006ye-Ia for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsmB5-0002XC-9F for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:48 -0400 Received: from ozlabs.ru ([107.173.13.209]:44668) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmB4-0002Ql-Rx for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:47 -0400 Received: from vpl1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 4F5003A60061; Fri, 15 Sep 2017 04:42:00 -0400 (EDT) From: Alexey Kardashevskiy To: qemu-devel@nongnu.org Date: Fri, 15 Sep 2017 18:40:27 +1000 Message-Id: <20170915084030.40988-11-aik@ozlabs.ru> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170915084030.40988-1-aik@ozlabs.ru> References: <20170915084030.40988-1-aik@ozlabs.ru> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 107.173.13.209 Subject: [Qemu-devel] [PATCH qemu v2 10/13] memory: Move root MR from AddressSpace to FlatView X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , Paolo Bonzini Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Alexey Kardashevskiy --- include/exec/memory.h | 2 +- hw/pci/pci.c | 3 ++- memory.c | 30 ++++++++++++++++-------------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/include/exec/memory.h b/include/exec/memory.h index 7816e5d655..be8cc1ccd3 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -308,7 +308,6 @@ struct AddressSpace { /* All fields are private. */ struct rcu_head rcu; char *name; - MemoryRegion *root; int ref_count; bool malloced; @@ -322,6 +321,7 @@ struct AddressSpace { }; FlatView *address_space_to_flatview(AddressSpace *as); +MemoryRegion *address_space_root(AddressSpace *as); /** * MemoryRegionSection: describes a fragment of a #MemoryRegion diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 353195d154..7bf82aac9f 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -90,7 +90,8 @@ static void pci_init_bus_master(PCIDevice *pci_dev) memory_region_init_alias(&pci_dev->bus_master_enable_region, OBJECT(pci_dev), "bus master", - dma_as->root, 0, memory_region_size(dma_as->root)); + address_space_root(dma_as), 0, + memory_region_size(address_space_root(dma_as))); memory_region_set_enabled(&pci_dev->bus_master_enable_region, false); memory_region_add_subregion(&pci_dev->bus_master_container_region, 0, &pci_dev->bus_master_enable_region); diff --git a/memory.c b/memory.c index 0651be49ac..29f8588945 100644 --- a/memory.c +++ b/memory.c @@ -231,6 +231,7 @@ struct FlatView { unsigned nr; unsigned nr_allocated; struct AddressSpaceDispatch *dispatch; + MemoryRegion *root; }; typedef struct AddressSpaceOps AddressSpaceOps; @@ -260,12 +261,14 @@ static bool flatrange_equal(FlatRange *a, FlatRange *b) && a->readonly == b->readonly; } -static FlatView *flatview_alloc(void) +static FlatView *flatview_alloc(MemoryRegion *mr_root) { FlatView *view; view = g_new0(FlatView, 1); view->ref = 1; + view->root = mr_root; + memory_region_ref(mr_root); return view; } @@ -298,6 +301,7 @@ static void flatview_destroy(FlatView *view) memory_region_unref(view->ranges[i].mr); } g_free(view->ranges); + memory_region_unref(view->root); g_free(view); } @@ -629,7 +633,7 @@ static AddressSpace *memory_region_to_address_space(MemoryRegion *mr) mr = mr->container; } QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { - if (mr == as->root) { + if (mr == as->current_map->root) { return as; } } @@ -728,7 +732,7 @@ static FlatView *generate_memory_topology(MemoryRegion *mr) { FlatView *view; - view = flatview_alloc(); + view = flatview_alloc(mr); if (mr) { render_memory_region(view, mr, int128_zero(), @@ -952,7 +956,7 @@ static void flatview_render_new(FlatView *old_view, FlatView *new_view) static void address_space_update_topology(AddressSpace *as) { FlatView *old_view = address_space_get_flatview(as); - FlatView *new_view = generate_memory_topology(as->root); + FlatView *new_view = generate_memory_topology(old_view->root); flatview_render_new(old_view, new_view); address_space_update_topology_pass(as, old_view, new_view, false); @@ -2680,12 +2684,10 @@ void memory_region_invalidate_mmio_ptr(MemoryRegion *mr, hwaddr offset, void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name) { - memory_region_ref(root); memory_region_transaction_begin(); as->ref_count = 1; - as->root = root; as->malloced = false; - as->current_map = flatview_alloc(); + as->current_map = flatview_alloc(root); as->ioeventfd_nb = 0; as->ioeventfds = NULL; QTAILQ_INIT(&as->listeners); @@ -2695,6 +2697,11 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name) memory_region_transaction_commit(); } +MemoryRegion *address_space_root(AddressSpace *as) +{ + return as->current_map->root; +} + static void do_address_space_destroy(AddressSpace *as) { bool do_free = as->malloced; @@ -2704,7 +2711,6 @@ static void do_address_space_destroy(AddressSpace *as) flatview_unref(as->current_map); g_free(as->name); g_free(as->ioeventfds); - memory_region_unref(as->root); if (do_free) { g_free(as); } @@ -2715,7 +2721,7 @@ AddressSpace *address_space_init_shareable(MemoryRegion *root, const char *name) AddressSpace *as; QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { - if (root == as->root && as->malloced) { + if (root == address_space_root(as) && as->malloced) { as->ref_count++; return as; } @@ -2729,15 +2735,12 @@ AddressSpace *address_space_init_shareable(MemoryRegion *root, const char *name) void address_space_destroy(AddressSpace *as) { - MemoryRegion *root = as->root; - as->ref_count--; if (as->ref_count) { return; } /* Flush out anything from MemoryListeners listening in on this */ memory_region_transaction_begin(); - as->root = NULL; memory_region_transaction_commit(); QTAILQ_REMOVE(&address_spaces, as, address_spaces_link); @@ -2745,7 +2748,6 @@ void address_space_destroy(AddressSpace *as) * entries that the guest should never use. Wait for the old * values to expire before freeing the data. */ - as->root = root; call_rcu(as, do_address_space_destroy, rcu); } @@ -2934,7 +2936,7 @@ void mtree_info(fprintf_function mon_printf, void *f, bool flatview) QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { mon_printf(f, "address-space: %s\n", as->name); - mtree_print_mr(mon_printf, f, as->root, 1, 0, &ml_head); + mtree_print_mr(mon_printf, f, address_space_root(as), 1, 0, &ml_head); mon_printf(f, "\n"); } From patchwork Fri Sep 15 08:40:28 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 814157 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3xtptp6lpCz9t2f for ; Fri, 15 Sep 2017 18:47:30 +1000 (AEST) Received: from localhost ([::1]:51979 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmHZ-0005Fn-1c for incoming@patchwork.ozlabs.org; Fri, 15 Sep 2017 04:47:29 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38269) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmB9-00071e-Oo for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsmB6-0002YM-Dw for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:51 -0400 Received: from ozlabs.ru ([107.173.13.209]:44668) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmB5-0002Ql-US for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:48 -0400 Received: from vpl1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 6F8EE3A60063; Fri, 15 Sep 2017 04:42:01 -0400 (EDT) From: Alexey Kardashevskiy To: qemu-devel@nongnu.org Date: Fri, 15 Sep 2017 18:40:28 +1000 Message-Id: <20170915084030.40988-12-aik@ozlabs.ru> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170915084030.40988-1-aik@ozlabs.ru> References: <20170915084030.40988-1-aik@ozlabs.ru> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 107.173.13.209 Subject: [Qemu-devel] [PATCH qemu v2 11/13] memory: Share FlatView's and dispatch trees between address spaces X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , Paolo Bonzini Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This allows sharing flat views between address spaces when the same root memory region is used when creating a new address space. This adds a global list of flat views and a list of attached address spaces per a flat view. Each address space references a flat view. Signed-off-by: Alexey Kardashevskiy --- include/exec/memory.h | 3 +- memory.c | 148 ++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 108 insertions(+), 43 deletions(-) diff --git a/include/exec/memory.h b/include/exec/memory.h index be8cc1ccd3..04993f8eca 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -308,8 +308,6 @@ struct AddressSpace { /* All fields are private. */ struct rcu_head rcu; char *name; - int ref_count; - bool malloced; /* Accessed via RCU. */ struct FlatView *current_map; @@ -318,6 +316,7 @@ struct AddressSpace { struct MemoryRegionIoeventfd *ioeventfds; QTAILQ_HEAD(memory_listeners_as, MemoryListener) listeners; QTAILQ_ENTRY(AddressSpace) address_spaces_link; + QTAILQ_ENTRY(AddressSpace) flat_view_link; }; FlatView *address_space_to_flatview(AddressSpace *as); diff --git a/memory.c b/memory.c index 29f8588945..f3da9379df 100644 --- a/memory.c +++ b/memory.c @@ -47,6 +47,9 @@ static QTAILQ_HEAD(memory_listeners, MemoryListener) memory_listeners static QTAILQ_HEAD(, AddressSpace) address_spaces = QTAILQ_HEAD_INITIALIZER(address_spaces); +static QTAILQ_HEAD(FlatViewList, FlatView) flat_views + = QTAILQ_HEAD_INITIALIZER(flat_views); + typedef struct AddrRange AddrRange; /* @@ -232,6 +235,8 @@ struct FlatView { unsigned nr_allocated; struct AddressSpaceDispatch *dispatch; MemoryRegion *root; + QTAILQ_ENTRY(FlatView) flat_views_link; + QTAILQ_HEAD(address_spaces, AddressSpace) address_spaces; }; typedef struct AddressSpaceOps AddressSpaceOps; @@ -269,6 +274,7 @@ static FlatView *flatview_alloc(MemoryRegion *mr_root) view->ref = 1; view->root = mr_root; memory_region_ref(mr_root); + QTAILQ_INIT(&view->address_spaces); return view; } @@ -953,28 +959,99 @@ static void flatview_render_new(FlatView *old_view, FlatView *new_view) address_space_dispatch_compact(new_view->dispatch); } -static void address_space_update_topology(AddressSpace *as) +static MemoryRegion *memory_region_unalias_entire(MemoryRegion *mr) { - FlatView *old_view = address_space_get_flatview(as); - FlatView *new_view = generate_memory_topology(old_view->root); - - flatview_render_new(old_view, new_view); - address_space_update_topology_pass(as, old_view, new_view, false); - address_space_update_topology_pass(as, old_view, new_view, true); - - /* Writes are protected by the BQL. */ - atomic_rcu_set(&as->current_map, new_view); - call_rcu(old_view, flatview_unref, rcu); - - /* Note that all the old MemoryRegions are still alive up to this - * point. This relieves most MemoryListeners from the need to - * ref/unref the MemoryRegions they get---unless they use them - * outside the iothread mutex, in which case precise reference - * counting is necessary. - */ - flatview_unref(old_view); - - address_space_update_ioeventfds(as); + while (mr->alias && !mr->alias_offset && + int128_ge(mr->size, mr->alias->size)) { + /* The alias is included in its entirety. Use it as + * the "real" root, so that we can share more FlatViews. + */ + mr = mr->alias; + } + + return mr; +} + +static bool flatview_can_share(FlatView *old_view, FlatView *new_view) +{ + MemoryRegion *old_root = memory_region_unalias_entire(old_view->root); + MemoryRegion *new_root = memory_region_unalias_entire(new_view->root); + + if (old_root == new_root) { + return true; + } + + if (!old_root->enabled && !new_root->enabled) { + return true; + } + + return false; +} + +static void flatview_update_topology(void) +{ + AddressSpace *as, *asnext; + FlatView *old_view, *new_view, *vnext; + struct FlatViewList fvs_tmp = QTAILQ_HEAD_INITIALIZER(fvs_tmp); + bool found; + + /* Build list of unique FlatViews, FV::root is the key */ + QTAILQ_FOREACH(old_view, &flat_views, flat_views_link) { + found = false; + QTAILQ_FOREACH(new_view, &fvs_tmp, flat_views_link) { + if (flatview_can_share(old_view, new_view)) { + found = true; + break; + } + } + if (found) { + continue; + } + + new_view = generate_memory_topology(old_view->root); + flatview_render_new(old_view, new_view); + QTAILQ_INSERT_TAIL(&fvs_tmp, new_view, flat_views_link); + } + + /* Replace old FVs with new ones */ + QTAILQ_FOREACH_SAFE(old_view, &flat_views, flat_views_link, vnext) { + flatview_ref(old_view); + + found = false; + QTAILQ_FOREACH(new_view, &fvs_tmp, flat_views_link) { + if (flatview_can_share(old_view, new_view)) { + found = true; + break; + } + } + assert(found); + + QTAILQ_FOREACH_SAFE(as, &old_view->address_spaces, flat_view_link, + asnext) { + address_space_update_topology_pass(as, old_view, new_view, false); + address_space_update_topology_pass(as, old_view, new_view, true); + + QTAILQ_REMOVE(&old_view->address_spaces, as, flat_view_link); + flatview_unref(old_view); + + atomic_rcu_set(&as->current_map, new_view); + + flatview_ref(new_view); + QTAILQ_INSERT_TAIL(&new_view->address_spaces, as, flat_view_link); + } + + QTAILQ_REMOVE(&flat_views, old_view, flat_views_link); + + flatview_unref(old_view); /* unref from beginning of the scope */ + } + + /* Copy new FVs to the global list */ + QTAILQ_FOREACH_SAFE(new_view, &fvs_tmp, flat_views_link, vnext) { + QTAILQ_REMOVE(&fvs_tmp, new_view, flat_views_link); + flatview_unref(new_view); + + QTAILQ_INSERT_HEAD(&flat_views, new_view, flat_views_link); + } } void memory_region_transaction_begin(void) @@ -994,9 +1071,10 @@ void memory_region_transaction_commit(void) if (!memory_region_transaction_depth) { if (memory_region_update_pending) { MEMORY_LISTENER_CALL_GLOBAL(begin, Forward); + flatview_update_topology(); QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { - address_space_update_topology(as); + address_space_update_ioeventfds(as); } memory_region_update_pending = false; MEMORY_LISTENER_CALL_GLOBAL(commit, Forward); @@ -2685,8 +2763,6 @@ void memory_region_invalidate_mmio_ptr(MemoryRegion *mr, hwaddr offset, void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name) { memory_region_transaction_begin(); - as->ref_count = 1; - as->malloced = false; as->current_map = flatview_alloc(root); as->ioeventfd_nb = 0; as->ioeventfds = NULL; @@ -2694,6 +2770,8 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name) QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link); as->name = g_strdup(name ? name : "anonymous"); memory_region_update_pending |= root->enabled; + QTAILQ_INSERT_TAIL(&flat_views, as->current_map, flat_views_link); + QTAILQ_INSERT_TAIL(&as->current_map->address_spaces, as, flat_view_link); memory_region_transaction_commit(); } @@ -2704,41 +2782,29 @@ MemoryRegion *address_space_root(AddressSpace *as) static void do_address_space_destroy(AddressSpace *as) { - bool do_free = as->malloced; - assert(QTAILQ_EMPTY(&as->listeners)); + QTAILQ_REMOVE(&as->current_map->address_spaces, as, flat_view_link); + flatview_unref(as->current_map); + g_free(as->name); g_free(as->ioeventfds); - if (do_free) { - g_free(as); - } + g_free(as); } AddressSpace *address_space_init_shareable(MemoryRegion *root, const char *name) { AddressSpace *as; - QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { - if (root == address_space_root(as) && as->malloced) { - as->ref_count++; - return as; - } - } - as = g_malloc0(sizeof *as); address_space_init(as, root, name); - as->malloced = true; + return as; } void address_space_destroy(AddressSpace *as) { - as->ref_count--; - if (as->ref_count) { - return; - } /* Flush out anything from MemoryListeners listening in on this */ memory_region_transaction_begin(); memory_region_transaction_commit(); From patchwork Fri Sep 15 08:40:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 814154 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3xtpsg6bv4z9sPr for ; Fri, 15 Sep 2017 18:46:31 +1000 (AEST) Received: from localhost ([::1]:51975 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmGb-0004Ch-Sn for incoming@patchwork.ozlabs.org; Fri, 15 Sep 2017 04:46:29 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38268) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmB9-00071d-On for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsmB7-0002Yr-DQ for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:51 -0400 Received: from ozlabs.ru ([107.173.13.209]:44668) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmB7-0002Ql-4J for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:49 -0400 Received: from vpl1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 913133A60065; Fri, 15 Sep 2017 04:42:02 -0400 (EDT) From: Alexey Kardashevskiy To: qemu-devel@nongnu.org Date: Fri, 15 Sep 2017 18:40:29 +1000 Message-Id: <20170915084030.40988-13-aik@ozlabs.ru> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170915084030.40988-1-aik@ozlabs.ru> References: <20170915084030.40988-1-aik@ozlabs.ru> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 107.173.13.209 Subject: [Qemu-devel] [PATCH qemu v2 12/13] memory: Get rid of address_space_init_shareable X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , Paolo Bonzini Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Since FlatViews are shared now and ASes not, this gets rid of address_space_init_shareable(). Signed-off-by: Alexey Kardashevskiy --- Squash to the previous one? It is a separate patch to make review easier, mostly. --- include/exec/memory.h | 17 ----------------- include/hw/arm/armv7m.h | 2 +- cpus.c | 5 +++-- hw/arm/armv7m.c | 9 ++++----- memory.c | 10 ---------- target/arm/cpu.c | 16 ++++++++-------- target/i386/cpu.c | 5 +++-- 7 files changed, 19 insertions(+), 45 deletions(-) diff --git a/include/exec/memory.h b/include/exec/memory.h index 04993f8eca..a550dc21e5 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1584,23 +1584,6 @@ MemTxResult memory_region_dispatch_write(MemoryRegion *mr, void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name); /** - * address_space_init_shareable: return an address space for a memory region, - * creating it if it does not already exist - * - * @root: a #MemoryRegion that routes addresses for the address space - * @name: an address space name. The name is only used for debugging - * output. - * - * This function will return a pointer to an existing AddressSpace - * which was initialized with the specified MemoryRegion, or it will - * create and initialize one if it does not already exist. The ASes - * are reference-counted, so the memory will be freed automatically - * when the AddressSpace is destroyed via address_space_destroy. - */ -AddressSpace *address_space_init_shareable(MemoryRegion *root, - const char *name); - -/** * address_space_destroy: destroy an address space * * Releases all resources associated with an address space. After an address space diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h index 10eb058027..008000fe11 100644 --- a/include/hw/arm/armv7m.h +++ b/include/hw/arm/armv7m.h @@ -21,7 +21,7 @@ typedef struct { SysBusDevice parent_obj; /*< public >*/ - AddressSpace *source_as; + AddressSpace source_as; MemoryRegion iomem; uint32_t base; MemoryRegion *source_memory; diff --git a/cpus.c b/cpus.c index 9bed61eefc..c9a624003a 100644 --- a/cpus.c +++ b/cpus.c @@ -1764,8 +1764,9 @@ void qemu_init_vcpu(CPUState *cpu) /* If the target cpu hasn't set up any address spaces itself, * give it the default one. */ - AddressSpace *as = address_space_init_shareable(cpu->memory, - "cpu-memory"); + AddressSpace *as = g_new0(AddressSpace, 1); + + address_space_init(as, cpu->memory, "cpu-memory"); cpu->num_ases = 1; cpu_address_space_init(cpu, as, 0); } diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index b64a409b40..4900339646 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -41,7 +41,7 @@ static MemTxResult bitband_read(void *opaque, hwaddr offset, /* Find address in underlying memory and round down to multiple of size */ addr = bitband_addr(s, offset) & (-size); - res = address_space_read(s->source_as, addr, attrs, buf, size); + res = address_space_read(&s->source_as, addr, attrs, buf, size); if (res) { return res; } @@ -66,7 +66,7 @@ static MemTxResult bitband_write(void *opaque, hwaddr offset, uint64_t value, /* Find address in underlying memory and round down to multiple of size */ addr = bitband_addr(s, offset) & (-size); - res = address_space_read(s->source_as, addr, attrs, buf, size); + res = address_space_read(&s->source_as, addr, attrs, buf, size); if (res) { return res; } @@ -79,7 +79,7 @@ static MemTxResult bitband_write(void *opaque, hwaddr offset, uint64_t value, } else { buf[bitpos >> 3] &= ~bit; } - return address_space_write(s->source_as, addr, attrs, buf, size); + return address_space_write(&s->source_as, addr, attrs, buf, size); } static const MemoryRegionOps bitband_ops = { @@ -111,8 +111,7 @@ static void bitband_realize(DeviceState *dev, Error **errp) return; } - s->source_as = address_space_init_shareable(s->source_memory, - "bitband-source"); + address_space_init(&s->source_as, s->source_memory, "bitband-source"); } /* Board init. */ diff --git a/memory.c b/memory.c index f3da9379df..06052e63a0 100644 --- a/memory.c +++ b/memory.c @@ -2793,16 +2793,6 @@ static void do_address_space_destroy(AddressSpace *as) g_free(as); } -AddressSpace *address_space_init_shareable(MemoryRegion *root, const char *name) -{ - AddressSpace *as; - - as = g_malloc0(sizeof *as); - address_space_init(as, root, name); - - return as; -} - void address_space_destroy(AddressSpace *as) { /* Flush out anything from MemoryListeners listening in on this */ diff --git a/target/arm/cpu.c b/target/arm/cpu.c index a1acce3c7a..8874763b4b 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -678,6 +678,9 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) CPUARMState *env = &cpu->env; int pagebits; Error *local_err = NULL; +#ifndef CONFIG_USER_ONLY + AddressSpace *as; +#endif cpu_exec_realizefn(cs, &local_err); if (local_err != NULL) { @@ -868,24 +871,21 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) #ifndef CONFIG_USER_ONLY if (cpu->has_el3 || arm_feature(env, ARM_FEATURE_M_SECURITY)) { - AddressSpace *as; + as = g_new0(AddressSpace, 1); cs->num_ases = 2; if (!cpu->secure_memory) { cpu->secure_memory = cs->memory; } - as = address_space_init_shareable(cpu->secure_memory, - "cpu-secure-memory"); + address_space_init(as, cpu->secure_memory, "cpu-secure-memory"); cpu_address_space_init(cs, as, ARMASIdx_S); } else { cs->num_ases = 1; } - - cpu_address_space_init(cs, - address_space_init_shareable(cs->memory, - "cpu-memory"), - ARMASIdx_NS); + as = g_new0(AddressSpace, 1); + address_space_init(as, cs->memory, "cpu-memory"); + cpu_address_space_init(cs, as, ARMASIdx_NS); #endif qemu_init_vcpu(cs); diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 69676e13e1..11178300ee 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -3741,10 +3741,11 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) #ifndef CONFIG_USER_ONLY if (tcg_enabled()) { - AddressSpace *as_normal = address_space_init_shareable(cs->memory, - "cpu-memory"); + AddressSpace *as_normal = g_new0(AddressSpace, 1); AddressSpace *as_smm = g_new(AddressSpace, 1); + address_space_init(as_normal, cs->memory, "cpu-memory"); + cpu->cpu_as_mem = g_new(MemoryRegion, 1); cpu->cpu_as_root = g_new(MemoryRegion, 1); From patchwork Fri Sep 15 08:40:30 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 814152 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3xtppn53VGz9sPr for ; Fri, 15 Sep 2017 18:44:01 +1000 (AEST) Received: from localhost ([::1]:51963 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmEB-0001y7-Nk for incoming@patchwork.ozlabs.org; Fri, 15 Sep 2017 04:43:59 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38279) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmBA-00072E-BE for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsmB8-0002ZY-IJ for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:52 -0400 Received: from ozlabs.ru ([107.173.13.209]:44668) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsmB8-0002Ql-8x for qemu-devel@nongnu.org; Fri, 15 Sep 2017 04:40:50 -0400 Received: from vpl1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id B24B23A60067; Fri, 15 Sep 2017 04:42:03 -0400 (EDT) From: Alexey Kardashevskiy To: qemu-devel@nongnu.org Date: Fri, 15 Sep 2017 18:40:30 +1000 Message-Id: <20170915084030.40988-14-aik@ozlabs.ru> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170915084030.40988-1-aik@ozlabs.ru> References: <20170915084030.40988-1-aik@ozlabs.ru> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 107.173.13.209 Subject: [Qemu-devel] [PATCH qemu v2 13/13] memory: Add flat views to HMP "info mtree" X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , Paolo Bonzini Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This adds a new switch to "info mtree" to print dispatch tree internals. Signed-off-by: Alexey Kardashevskiy --- Example: aik@fstn1-p1:~$ echo "info mtree -f -d" | nc localhost 30000 QEMU 2.9.94 monitor - type 'help' for more information (qemu) info mtree -f -d FlatView #0 AS "memory" AS "cpu-memory" AS "cpu-memory" AS "cpu-memory" AS "cpu-memory" AS "cpu-memory" AS "cpu-memory" AS "cpu-memory" AS "cpu-memory" Root memory region: system 0000000000000000-000000007fffffff (prio 0, ram): ppc_spapr.ram Dispatch Physical sections #0 @0000000000000000..ffffffffffffffff (noname) [unassigned] #1 @0000000000000000..ffffffffffffffff (noname) [not dirty] #2 @0000000000000000..ffffffffffffffff (noname) [ROM] #3 @0000000000000000..ffffffffffffffff (noname) [watch] #4 @0000000000000000..000000007fffffff ppc_spapr.ram [MRU] Nodes (9 bits per level, 6 levels) ptr=[3] skip=4 [0] 0 skip=3 ptr=[3] 1..511 skip=1 ptr=NIL [1] 0 skip=2 ptr=[3] 1..511 skip=1 ptr=NIL [2] 0 skip=1 ptr=[3] 1..511 skip=1 ptr=NIL [3] 0..1 skip=0 ptr=#4 2..511 skip=1 ptr=NIL FlatView #1 AS "I/O" Root memory region: io 0000000000000000-000000000000ffff (prio 0, i/o): io Dispatch Physical sections #0 @0000000000000000..ffffffffffffffff (noname) [unassigned] #1 @0000000000000000..ffffffffffffffff (noname) [not dirty] #2 @0000000000000000..ffffffffffffffff (noname) [ROM] #3 @0000000000000000..ffffffffffffffff (noname) [watch] #4 @0000000000000000..000000000000ffff io [ROOT] Nodes (9 bits per level, 6 levels) ptr=[5] skip=6 [0] 0 skip=5 ptr=[5] 1..511 skip=1 ptr=NIL [1] 0 skip=4 ptr=[5] 1..511 skip=1 ptr=NIL [2] 0 skip=3 ptr=[5] 1..511 skip=1 ptr=NIL [3] 0 skip=2 ptr=[5] 1..511 skip=1 ptr=NIL [4] 0 skip=1 ptr=[5] 1..511 skip=1 ptr=NIL [5] 0..15 skip=0 ptr=#4 16..511 skip=0 ptr=#0 FlatView #2 AS "pci@800000020000000" Root memory region: pci@800000020000000.iommu-root 0000000000000000-000000003fffffff (prio 0, i/o): tce-iommu-80000000 0000040000000000-000004000000ffff (prio 0, i/o): msi Dispatch Physical sections #0 @0000000000000000..ffffffffffffffff (noname) [unassigned] #1 @0000000000000000..ffffffffffffffff (noname) [not dirty] #2 @0000000000000000..ffffffffffffffff (noname) [ROM] #3 @0000000000000000..ffffffffffffffff (noname) [watch] #4 @0000000000000000..000000003fffffff tce-iommu-80000000 [iommu] #5 @0000040000000000..000004000000ffff msi Nodes (9 bits per level, 6 levels) ptr=[2] skip=3 [0] 0 skip=2 ptr=[2] 1..511 skip=1 ptr=NIL [1] 0 skip=1 ptr=[2] 1..511 skip=1 ptr=NIL [2] 0 skip=0 ptr=#4 1..7 skip=1 ptr=NIL 8 skip=3 ptr=[6] 9..511 skip=1 ptr=NIL [3] 0 skip=0 ptr=#4 1..511 skip=1 ptr=NIL [4] 0 skip=2 ptr=[6] 1..511 skip=1 ptr=NIL [5] 0 skip=1 ptr=[6] 1..511 skip=1 ptr=NIL [6] 0..15 skip=0 ptr=#5 16..511 skip=0 ptr=#0 FlatView #3 AS "" Root memory region: bus master container --- include/exec/memory-internal.h | 4 ++ include/exec/memory.h | 3 +- exec.c | 84 ++++++++++++++++++++++++++++++++++++++++++ memory.c | 41 ++++++++++++++++----- monitor.c | 3 +- hmp-commands-info.hx | 7 ++-- 6 files changed, 128 insertions(+), 14 deletions(-) diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index e87a30fcae..07295dba7e 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -36,5 +36,9 @@ AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as); AddressSpaceDispatch *flatview_to_dispatch(FlatView *fv); void address_space_dispatch_free(AddressSpaceDispatch *d); +void mtree_print_dispatch(fprintf_function mon, void *f, + struct AddressSpaceDispatch *d, + MemoryRegion *root); + #endif #endif diff --git a/include/exec/memory.h b/include/exec/memory.h index a550dc21e5..3dd876f01a 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1514,7 +1514,8 @@ void memory_global_dirty_log_start(void); */ void memory_global_dirty_log_stop(void); -void mtree_info(fprintf_function mon_printf, void *f, bool flatview); +void mtree_info(fprintf_function mon_printf, void *f, bool flatview, + bool dispatch_tree); /** * memory_region_request_mmio_ptr: request a pointer to an mmio diff --git a/exec.c b/exec.c index 11e0e3c927..a79daf1853 100644 --- a/exec.c +++ b/exec.c @@ -3622,3 +3622,87 @@ void page_size_init(void) } qemu_host_page_mask = -(intptr_t)qemu_host_page_size; } + +#if !defined(CONFIG_USER_ONLY) + +static void mtree_print_phys_entries(fprintf_function mon, void *f, + int start, int end, int skip, int ptr) +{ + if (start == end - 1) { + mon(f, "\t%3d ", start); + } else { + mon(f, "\t%3d..%-3d ", start, end - 1); + } + mon(f, " skip=%d ", skip); + if (ptr == PHYS_MAP_NODE_NIL) { + mon(f, " ptr=NIL"); + } else if (!skip) { + mon(f, " ptr=#%d", ptr); + } else { + mon(f, " ptr=[%d]", ptr); + } + mon(f, "\n"); +} + +#define MR_SIZE(size) (int128_nz(size) ? (hwaddr)int128_get64( \ + int128_sub((size), int128_one())) : 0) + +void mtree_print_dispatch(fprintf_function mon, void *f, + AddressSpaceDispatch *d, MemoryRegion *root) +{ + int i; + + mon(f, " Dispatch\n"); + mon(f, " Physical sections\n"); + + for (i = 0; i < d->map.sections_nb; ++i) { + MemoryRegionSection *s = d->map.sections + i; + const char *names[] = { " [unassigned]", " [not dirty]", + " [ROM]", " [watch]" }; + + mon(f, " #%d @" TARGET_FMT_plx ".." TARGET_FMT_plx " %s%s%s%s%s", + i, + s->offset_within_address_space, + s->offset_within_address_space + MR_SIZE(s->mr->size), + s->mr->name ? s->mr->name : "(noname)", + i < ARRAY_SIZE(names) ? names[i] : "", + s->mr == root ? " [ROOT]" : "", + s == d->mru_section ? " [MRU]" : "", + s->mr->is_iommu ? " [iommu]" : ""); + + if (s->mr->alias) { + mon(f, " alias=%s", s->mr->alias->name ? + s->mr->alias->name : "noname"); + } + mon(f, "\n"); + } + + mon(f, " Nodes (%d bits per level, %d levels) ptr=[%d] skip=%d\n", + P_L2_BITS, P_L2_LEVELS, d->phys_map.ptr, d->phys_map.skip); + for (i = 0; i < d->map.nodes_nb; ++i) { + int j, jprev; + PhysPageEntry prev; + Node *n = d->map.nodes + i; + + mon(f, " [%d]\n", i); + + for (j = 0, jprev = 0, prev = *n[0]; j < ARRAY_SIZE(*n); ++j) { + PhysPageEntry *pe = *n + j; + + if (pe->ptr == prev.ptr && pe->skip == prev.skip) { + continue; + } + + mtree_print_phys_entries(mon, f, jprev, j, prev.skip, prev.ptr); + + jprev = j; + prev = *pe; + } + + if (jprev != ARRAY_SIZE(*n)) { + mtree_print_phys_entries(mon, f, jprev, j, prev.skip, prev.ptr); + } + } +} + +#endif diff --git a/memory.c b/memory.c index 06052e63a0..ad2830a1bb 100644 --- a/memory.c +++ b/memory.c @@ -2933,17 +2933,26 @@ static void mtree_print_mr(fprintf_function mon_printf, void *f, } static void mtree_print_flatview(fprintf_function p, void *f, - AddressSpace *as) + FlatView *view) { - FlatView *view = address_space_get_flatview(as); FlatRange *range = &view->ranges[0]; MemoryRegion *mr; int n = view->nr; + AddressSpace *as; + + QTAILQ_FOREACH(as, &view->address_spaces, flat_view_link) { + p(f, " AS \"%s\"\n", as->name); + } + + p(f, " Root memory region: %s", memory_region_name(view->root)); + if (view->root->alias) { + p(f, " alias %s", memory_region_name(view->root->alias)); + } + p(f, "\n"); if (n <= 0) { p(f, MTREE_INDENT "No rendered FlatView for " "address space '%s'\n", as->name); - flatview_unref(view); return; } @@ -2969,21 +2978,35 @@ static void mtree_print_flatview(fprintf_function p, void *f, } range++; } - - flatview_unref(view); } -void mtree_info(fprintf_function mon_printf, void *f, bool flatview) +void mtree_info(fprintf_function mon_printf, void *f, bool flatview, + bool dispatch_tree) { MemoryRegionListHead ml_head; MemoryRegionList *ml, *ml2; AddressSpace *as; + FlatView *view; + int n; if (flatview) { - QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { - mon_printf(f, "address-space (flat view): %s\n", as->name); - mtree_print_flatview(mon_printf, f, as); + n = 0; + QTAILQ_FOREACH(view, &flat_views, flat_views_link) { + flatview_ref(view); + + mon_printf(f, "FlatView #%d\n", n); + ++n; + + mtree_print_flatview(mon_printf, f, view); +#if !defined(CONFIG_USER_ONLY) + if (dispatch_tree) { + mtree_print_dispatch(mon_printf, f, view->dispatch, + view->root); + } +#endif mon_printf(f, "\n"); + + flatview_unref(view); } return; } diff --git a/monitor.c b/monitor.c index 058045b3cb..f4856b9268 100644 --- a/monitor.c +++ b/monitor.c @@ -1703,8 +1703,9 @@ static void hmp_boot_set(Monitor *mon, const QDict *qdict) static void hmp_info_mtree(Monitor *mon, const QDict *qdict) { bool flatview = qdict_get_try_bool(qdict, "flatview", false); + bool dispatch_tree = qdict_get_try_bool(qdict, "dispatch_tree", false); - mtree_info((fprintf_function)monitor_printf, mon, flatview); + mtree_info((fprintf_function)monitor_printf, mon, flatview, dispatch_tree); } static void hmp_info_numa(Monitor *mon, const QDict *qdict) diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx index 1c6772597d..4f1ece93e5 100644 --- a/hmp-commands-info.hx +++ b/hmp-commands-info.hx @@ -250,9 +250,10 @@ ETEXI { .name = "mtree", - .args_type = "flatview:-f", - .params = "[-f]", - .help = "show memory tree (-f: dump flat view for address spaces)", + .args_type = "flatview:-f,dispatch_tree:-d", + .params = "[-f][-d]", + .help = "show memory tree (-f: dump flat view for address spaces;" + "-d: dump dispatch tree, valid with -f only)", .cmd = hmp_info_mtree, },