|
|
9bac43 |
From 30acf078fced0fac523d4773fe06983d4cfce64d Mon Sep 17 00:00:00 2001
|
|
|
9bac43 |
From: David Gibson <dgibson@redhat.com>
|
|
|
9bac43 |
Date: Thu, 16 Nov 2017 03:07:17 +0100
|
|
|
9bac43 |
Subject: [PATCH 13/30] memory: Move AddressSpaceDispatch from AddressSpace to
|
|
|
9bac43 |
FlatView
|
|
|
9bac43 |
|
|
|
9bac43 |
RH-Author: David Gibson <dgibson@redhat.com>
|
|
|
9bac43 |
Message-id: <20171116030732.8560-8-dgibson@redhat.com>
|
|
|
9bac43 |
Patchwork-id: 77697
|
|
|
9bac43 |
O-Subject: [PATCH 07/22] memory: Move AddressSpaceDispatch from AddressSpace to FlatView
|
|
|
9bac43 |
Bugzilla: 1481593
|
|
|
9bac43 |
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
|
|
9bac43 |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
9bac43 |
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
|
|
|
9bac43 |
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
|
|
9bac43 |
|
|
|
9bac43 |
From: Alexey Kardashevskiy <aik@ozlabs.ru>
|
|
|
9bac43 |
|
|
|
9bac43 |
As we are going to share FlatView's between AddressSpace's,
|
|
|
9bac43 |
and AddressSpaceDispatch is a structure to perform quick lookup
|
|
|
9bac43 |
in FlatView, this moves ASD to FlatView.
|
|
|
9bac43 |
|
|
|
9bac43 |
After previosly open coded ASD rendering, we can also remove
|
|
|
9bac43 |
as->next_dispatch as the new FlatView pointer is stored
|
|
|
9bac43 |
on a stack and set to an AS atomically.
|
|
|
9bac43 |
|
|
|
9bac43 |
flatview_destroy() is executed under RCU instead of
|
|
|
9bac43 |
address_space_dispatch_free() now.
|
|
|
9bac43 |
|
|
|
9bac43 |
This makes mem_begin/mem_commit to work with ASD and mem_add with FV
|
|
|
9bac43 |
as later on mem_add will be taking FV as an argument anyway.
|
|
|
9bac43 |
|
|
|
9bac43 |
This should cause no behavioural change.
|
|
|
9bac43 |
|
|
|
9bac43 |
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
|
|
|
9bac43 |
Message-Id: <20170921085110.25598-5-aik@ozlabs.ru>
|
|
|
9bac43 |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
9bac43 |
(cherry picked from commit 66a6df1dc6d5b28cc3e65db0d71683fbdddc6b62)
|
|
|
9bac43 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9bac43 |
|
|
|
9bac43 |
Conflicts:
|
|
|
9bac43 |
exec.c
|
|
|
9bac43 |
|
|
|
9bac43 |
Conflicts because we applied d5e5fafd "exec: add page_mask for
|
|
|
9bac43 |
flatview_do_translate" out of order downstream.
|
|
|
9bac43 |
|
|
|
9bac43 |
Signed-off-by: David Gibson <dgibson@redhat.com>
|
|
|
9bac43 |
---
|
|
|
9bac43 |
exec.c | 41 +++++++++++------------------------------
|
|
|
9bac43 |
include/exec/memory-internal.h | 12 +++++++-----
|
|
|
9bac43 |
include/exec/memory.h | 2 --
|
|
|
9bac43 |
memory.c | 31 ++++++++++++++++++++++++-------
|
|
|
9bac43 |
4 files changed, 42 insertions(+), 44 deletions(-)
|
|
|
9bac43 |
|
|
|
9bac43 |
diff --git a/exec.c b/exec.c
|
|
|
9bac43 |
index 4fed7b7..3c0b4f8 100644
|
|
|
9bac43 |
--- a/exec.c
|
|
|
9bac43 |
+++ b/exec.c
|
|
|
9bac43 |
@@ -188,8 +188,6 @@ typedef struct PhysPageMap {
|
|
|
9bac43 |
} PhysPageMap;
|
|
|
9bac43 |
|
|
|
9bac43 |
struct AddressSpaceDispatch {
|
|
|
9bac43 |
- struct rcu_head rcu;
|
|
|
9bac43 |
-
|
|
|
9bac43 |
MemoryRegionSection *mru_section;
|
|
|
9bac43 |
/* This is a multi-level map on the physical address space.
|
|
|
9bac43 |
* The bottom level has pointers to MemoryRegionSections.
|
|
|
9bac43 |
@@ -493,7 +491,7 @@ static MemoryRegionSection address_space_do_translate(AddressSpace *as,
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
for (;;) {
|
|
|
9bac43 |
- AddressSpaceDispatch *d = atomic_rcu_read(&as->dispatch);
|
|
|
9bac43 |
+ AddressSpaceDispatch *d = address_space_to_dispatch(as);
|
|
|
9bac43 |
section = address_space_translate_internal(d, addr, &addr, &plen, is_mmio);
|
|
|
9bac43 |
|
|
|
9bac43 |
iommu_mr = memory_region_get_iommu(section->mr);
|
|
|
9bac43 |
@@ -1233,7 +1231,7 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu,
|
|
|
9bac43 |
} else {
|
|
|
9bac43 |
AddressSpaceDispatch *d;
|
|
|
9bac43 |
|
|
|
9bac43 |
- d = atomic_rcu_read(§ion->address_space->dispatch);
|
|
|
9bac43 |
+ d = address_space_to_dispatch(section->address_space);
|
|
|
9bac43 |
iotlb = section - d->map.sections;
|
|
|
9bac43 |
iotlb += xlat;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
@@ -1358,9 +1356,9 @@ static void register_multipage(AddressSpaceDispatch *d,
|
|
|
9bac43 |
phys_page_set(d, start_addr >> TARGET_PAGE_BITS, num_pages, section_index);
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
-void mem_add(AddressSpace *as, MemoryRegionSection *section)
|
|
|
9bac43 |
+void mem_add(AddressSpace *as, FlatView *fv, MemoryRegionSection *section)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
- AddressSpaceDispatch *d = as->next_dispatch;
|
|
|
9bac43 |
+ AddressSpaceDispatch *d = flatview_to_dispatch(fv);
|
|
|
9bac43 |
MemoryRegionSection now = *section, remain = *section;
|
|
|
9bac43 |
Int128 page_size = int128_make64(TARGET_PAGE_SIZE);
|
|
|
9bac43 |
|
|
|
9bac43 |
@@ -2683,7 +2681,7 @@ static void io_mem_init(void)
|
|
|
9bac43 |
NULL, UINT64_MAX);
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
-void mem_begin(AddressSpace *as)
|
|
|
9bac43 |
+AddressSpaceDispatch *mem_begin(AddressSpace *as)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
AddressSpaceDispatch *d = g_new0(AddressSpaceDispatch, 1);
|
|
|
9bac43 |
uint16_t n;
|
|
|
9bac43 |
@@ -2699,26 +2697,19 @@ void mem_begin(AddressSpace *as)
|
|
|
9bac43 |
|
|
|
9bac43 |
d->phys_map = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .skip = 1 };
|
|
|
9bac43 |
d->as = as;
|
|
|
9bac43 |
- as->next_dispatch = d;
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ return d;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
-static void address_space_dispatch_free(AddressSpaceDispatch *d)
|
|
|
9bac43 |
+void address_space_dispatch_free(AddressSpaceDispatch *d)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
phys_sections_free(&d->map);
|
|
|
9bac43 |
g_free(d);
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
-void mem_commit(AddressSpace *as)
|
|
|
9bac43 |
+void mem_commit(AddressSpaceDispatch *d)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
- AddressSpaceDispatch *cur = as->dispatch;
|
|
|
9bac43 |
- AddressSpaceDispatch *next = as->next_dispatch;
|
|
|
9bac43 |
-
|
|
|
9bac43 |
- phys_page_compact_all(next, next->map.nodes_nb);
|
|
|
9bac43 |
-
|
|
|
9bac43 |
- atomic_rcu_set(&as->dispatch, next);
|
|
|
9bac43 |
- if (cur) {
|
|
|
9bac43 |
- call_rcu(cur, address_space_dispatch_free, rcu);
|
|
|
9bac43 |
- }
|
|
|
9bac43 |
+ phys_page_compact_all(d, d->map.nodes_nb);
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
static void tcg_commit(MemoryListener *listener)
|
|
|
9bac43 |
@@ -2734,21 +2725,11 @@ static void tcg_commit(MemoryListener *listener)
|
|
|
9bac43 |
* We reload the dispatch pointer now because cpu_reloading_memory_map()
|
|
|
9bac43 |
* may have split the RCU critical section.
|
|
|
9bac43 |
*/
|
|
|
9bac43 |
- d = atomic_rcu_read(&cpuas->as->dispatch);
|
|
|
9bac43 |
+ d = address_space_to_dispatch(cpuas->as);
|
|
|
9bac43 |
atomic_rcu_set(&cpuas->memory_dispatch, d);
|
|
|
9bac43 |
tlb_flush(cpuas->cpu);
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
-void address_space_destroy_dispatch(AddressSpace *as)
|
|
|
9bac43 |
-{
|
|
|
9bac43 |
- AddressSpaceDispatch *d = as->dispatch;
|
|
|
9bac43 |
-
|
|
|
9bac43 |
- atomic_rcu_set(&as->dispatch, NULL);
|
|
|
9bac43 |
- if (d) {
|
|
|
9bac43 |
- call_rcu(d, address_space_dispatch_free, rcu);
|
|
|
9bac43 |
- }
|
|
|
9bac43 |
-}
|
|
|
9bac43 |
-
|
|
|
9bac43 |
static void memory_map_init(void)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
system_memory = g_malloc(sizeof(*system_memory));
|
|
|
9bac43 |
diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h
|
|
|
9bac43 |
index 9abde2f..6e08eda 100644
|
|
|
9bac43 |
--- a/include/exec/memory-internal.h
|
|
|
9bac43 |
+++ b/include/exec/memory-internal.h
|
|
|
9bac43 |
@@ -22,16 +22,18 @@
|
|
|
9bac43 |
#ifndef CONFIG_USER_ONLY
|
|
|
9bac43 |
typedef struct AddressSpaceDispatch AddressSpaceDispatch;
|
|
|
9bac43 |
|
|
|
9bac43 |
-void address_space_destroy_dispatch(AddressSpace *as);
|
|
|
9bac43 |
-
|
|
|
9bac43 |
extern const MemoryRegionOps unassigned_mem_ops;
|
|
|
9bac43 |
|
|
|
9bac43 |
bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
|
|
|
9bac43 |
unsigned size, bool is_write);
|
|
|
9bac43 |
|
|
|
9bac43 |
-void mem_add(AddressSpace *as, MemoryRegionSection *section);
|
|
|
9bac43 |
-void mem_begin(AddressSpace *as);
|
|
|
9bac43 |
-void mem_commit(AddressSpace *as);
|
|
|
9bac43 |
+void mem_add(AddressSpace *as, FlatView *fv, MemoryRegionSection *section);
|
|
|
9bac43 |
+AddressSpaceDispatch *mem_begin(AddressSpace *as);
|
|
|
9bac43 |
+void mem_commit(AddressSpaceDispatch *d);
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as);
|
|
|
9bac43 |
+AddressSpaceDispatch *flatview_to_dispatch(FlatView *fv);
|
|
|
9bac43 |
+void address_space_dispatch_free(AddressSpaceDispatch *d);
|
|
|
9bac43 |
|
|
|
9bac43 |
#endif
|
|
|
9bac43 |
#endif
|
|
|
9bac43 |
diff --git a/include/exec/memory.h b/include/exec/memory.h
|
|
|
9bac43 |
index 9ee0f2e..8f26d63 100644
|
|
|
9bac43 |
--- a/include/exec/memory.h
|
|
|
9bac43 |
+++ b/include/exec/memory.h
|
|
|
9bac43 |
@@ -326,8 +326,6 @@ struct AddressSpace {
|
|
|
9bac43 |
|
|
|
9bac43 |
int ioeventfd_nb;
|
|
|
9bac43 |
struct MemoryRegionIoeventfd *ioeventfds;
|
|
|
9bac43 |
- struct AddressSpaceDispatch *dispatch;
|
|
|
9bac43 |
- struct AddressSpaceDispatch *next_dispatch;
|
|
|
9bac43 |
QTAILQ_HEAD(memory_listeners_as, MemoryListener) listeners;
|
|
|
9bac43 |
QTAILQ_ENTRY(AddressSpace) address_spaces_link;
|
|
|
9bac43 |
};
|
|
|
9bac43 |
diff --git a/memory.c b/memory.c
|
|
|
9bac43 |
index f51e499..41e2e67 100644
|
|
|
9bac43 |
--- a/memory.c
|
|
|
9bac43 |
+++ b/memory.c
|
|
|
9bac43 |
@@ -229,6 +229,7 @@ struct FlatView {
|
|
|
9bac43 |
FlatRange *ranges;
|
|
|
9bac43 |
unsigned nr;
|
|
|
9bac43 |
unsigned nr_allocated;
|
|
|
9bac43 |
+ struct AddressSpaceDispatch *dispatch;
|
|
|
9bac43 |
};
|
|
|
9bac43 |
|
|
|
9bac43 |
typedef struct AddressSpaceOps AddressSpaceOps;
|
|
|
9bac43 |
@@ -289,6 +290,9 @@ static void flatview_destroy(FlatView *view)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
int i;
|
|
|
9bac43 |
|
|
|
9bac43 |
+ if (view->dispatch) {
|
|
|
9bac43 |
+ address_space_dispatch_free(view->dispatch);
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
for (i = 0; i < view->nr; i++) {
|
|
|
9bac43 |
memory_region_unref(view->ranges[i].mr);
|
|
|
9bac43 |
}
|
|
|
9bac43 |
@@ -304,10 +308,25 @@ static bool flatview_ref(FlatView *view)
|
|
|
9bac43 |
static void flatview_unref(FlatView *view)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
if (atomic_fetch_dec(&view->ref) == 1) {
|
|
|
9bac43 |
- flatview_destroy(view);
|
|
|
9bac43 |
+ call_rcu(view, flatview_destroy, rcu);
|
|
|
9bac43 |
}
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
+static FlatView *address_space_to_flatview(AddressSpace *as)
|
|
|
9bac43 |
+{
|
|
|
9bac43 |
+ return atomic_rcu_read(&as->current_map);
|
|
|
9bac43 |
+}
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+AddressSpaceDispatch *flatview_to_dispatch(FlatView *fv)
|
|
|
9bac43 |
+{
|
|
|
9bac43 |
+ return fv->dispatch;
|
|
|
9bac43 |
+}
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as)
|
|
|
9bac43 |
+{
|
|
|
9bac43 |
+ return flatview_to_dispatch(address_space_to_flatview(as));
|
|
|
9bac43 |
+}
|
|
|
9bac43 |
+
|
|
|
9bac43 |
static bool can_merge(FlatRange *r1, FlatRange *r2)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
return int128_eq(addrrange_end(r1->addr), r2->addr.start)
|
|
|
9bac43 |
@@ -890,13 +909,13 @@ static void address_space_update_topology(AddressSpace *as)
|
|
|
9bac43 |
FlatView *new_view = generate_memory_topology(as->root);
|
|
|
9bac43 |
int i;
|
|
|
9bac43 |
|
|
|
9bac43 |
- mem_begin(as);
|
|
|
9bac43 |
+ new_view->dispatch = mem_begin(as);
|
|
|
9bac43 |
for (i = 0; i < new_view->nr; i++) {
|
|
|
9bac43 |
MemoryRegionSection mrs =
|
|
|
9bac43 |
section_from_flat_range(&new_view->ranges[i], as);
|
|
|
9bac43 |
- mem_add(as, &mrs);
|
|
|
9bac43 |
+ mem_add(as, new_view, &mrs);
|
|
|
9bac43 |
}
|
|
|
9bac43 |
- mem_commit(as);
|
|
|
9bac43 |
+ mem_commit(new_view->dispatch);
|
|
|
9bac43 |
|
|
|
9bac43 |
if (!QTAILQ_EMPTY(&as->listeners)) {
|
|
|
9bac43 |
address_space_update_topology_pass(as, old_view, new_view, false);
|
|
|
9bac43 |
@@ -905,7 +924,7 @@ static void address_space_update_topology(AddressSpace *as)
|
|
|
9bac43 |
|
|
|
9bac43 |
/* Writes are protected by the BQL. */
|
|
|
9bac43 |
atomic_rcu_set(&as->current_map, new_view);
|
|
|
9bac43 |
- call_rcu(old_view, flatview_unref, rcu);
|
|
|
9bac43 |
+ flatview_unref(old_view);
|
|
|
9bac43 |
|
|
|
9bac43 |
/* Note that all the old MemoryRegions are still alive up to this
|
|
|
9bac43 |
* point. This relieves most MemoryListeners from the need to
|
|
|
9bac43 |
@@ -2635,7 +2654,6 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
|
|
|
9bac43 |
QTAILQ_INIT(&as->listeners);
|
|
|
9bac43 |
QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
|
|
|
9bac43 |
as->name = g_strdup(name ? name : "anonymous");
|
|
|
9bac43 |
- as->dispatch = NULL;
|
|
|
9bac43 |
memory_region_update_pending |= root->enabled;
|
|
|
9bac43 |
memory_region_transaction_commit();
|
|
|
9bac43 |
}
|
|
|
9bac43 |
@@ -2644,7 +2662,6 @@ static void do_address_space_destroy(AddressSpace *as)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
bool do_free = as->malloced;
|
|
|
9bac43 |
|
|
|
9bac43 |
- address_space_destroy_dispatch(as);
|
|
|
9bac43 |
assert(QTAILQ_EMPTY(&as->listeners));
|
|
|
9bac43 |
|
|
|
9bac43 |
flatview_unref(as->current_map);
|
|
|
9bac43 |
--
|
|
|
9bac43 |
1.8.3.1
|
|
|
9bac43 |
|