|
|
9bac43 |
From 6a1a074890aa228417dffb2afb49f56234e99c8d Mon Sep 17 00:00:00 2001
|
|
|
9bac43 |
From: David Gibson <dgibson@redhat.com>
|
|
|
9bac43 |
Date: Thu, 16 Nov 2017 03:07:27 +0100
|
|
|
9bac43 |
Subject: [PATCH 23/30] memory: Rework "info mtree" to print flat views and
|
|
|
9bac43 |
dispatch trees
|
|
|
9bac43 |
|
|
|
9bac43 |
RH-Author: David Gibson <dgibson@redhat.com>
|
|
|
9bac43 |
Message-id: <20171116030732.8560-18-dgibson@redhat.com>
|
|
|
9bac43 |
Patchwork-id: 77709
|
|
|
9bac43 |
O-Subject: [PATCH 17/22] memory: Rework "info mtree" to print flat views and dispatch trees
|
|
|
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 |
This adds a new "-d" switch to "info mtree" to print dispatch tree
|
|
|
9bac43 |
internals.
|
|
|
9bac43 |
|
|
|
9bac43 |
This changes the way "-f" is handled - it prints now flat views and
|
|
|
9bac43 |
associated address spaces.
|
|
|
9bac43 |
|
|
|
9bac43 |
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
|
|
|
9bac43 |
Message-Id: <20170921085110.25598-15-aik@ozlabs.ru>
|
|
|
9bac43 |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
9bac43 |
(cherry picked from commit 5e8fd947e2670c3c18f139de6a83fafcb56abbcc)
|
|
|
9bac43 |
|
|
|
9bac43 |
Signed-off-by: David Gibson <dgibson@redhat.com>
|
|
|
9bac43 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9bac43 |
---
|
|
|
9bac43 |
exec.c | 84 +++++++++++++++++++++++++++++++++++++++
|
|
|
9bac43 |
hmp-commands-info.hx | 7 ++--
|
|
|
9bac43 |
include/exec/memory-internal.h | 4 ++
|
|
|
9bac43 |
include/exec/memory.h | 3 +-
|
|
|
9bac43 |
memory.c | 90 +++++++++++++++++++++++++++++++++++++-----
|
|
|
9bac43 |
monitor.c | 3 +-
|
|
|
9bac43 |
6 files changed, 176 insertions(+), 15 deletions(-)
|
|
|
9bac43 |
|
|
|
9bac43 |
diff --git a/exec.c b/exec.c
|
|
|
9bac43 |
index 1b30e1e..5a12e55 100644
|
|
|
9bac43 |
--- a/exec.c
|
|
|
9bac43 |
+++ b/exec.c
|
|
|
9bac43 |
@@ -3628,3 +3628,87 @@ void page_size_init(void)
|
|
|
9bac43 |
}
|
|
|
9bac43 |
qemu_host_page_mask = -(intptr_t)qemu_host_page_size;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+#if !defined(CONFIG_USER_ONLY)
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+static void mtree_print_phys_entries(fprintf_function mon, void *f,
|
|
|
9bac43 |
+ int start, int end, int skip, int ptr)
|
|
|
9bac43 |
+{
|
|
|
9bac43 |
+ if (start == end - 1) {
|
|
|
9bac43 |
+ mon(f, "\t%3d ", start);
|
|
|
9bac43 |
+ } else {
|
|
|
9bac43 |
+ mon(f, "\t%3d..%-3d ", start, end - 1);
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+ mon(f, " skip=%d ", skip);
|
|
|
9bac43 |
+ if (ptr == PHYS_MAP_NODE_NIL) {
|
|
|
9bac43 |
+ mon(f, " ptr=NIL");
|
|
|
9bac43 |
+ } else if (!skip) {
|
|
|
9bac43 |
+ mon(f, " ptr=#%d", ptr);
|
|
|
9bac43 |
+ } else {
|
|
|
9bac43 |
+ mon(f, " ptr=[%d]", ptr);
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+ mon(f, "\n");
|
|
|
9bac43 |
+}
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+#define MR_SIZE(size) (int128_nz(size) ? (hwaddr)int128_get64( \
|
|
|
9bac43 |
+ int128_sub((size), int128_one())) : 0)
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+void mtree_print_dispatch(fprintf_function mon, void *f,
|
|
|
9bac43 |
+ AddressSpaceDispatch *d, MemoryRegion *root)
|
|
|
9bac43 |
+{
|
|
|
9bac43 |
+ int i;
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ mon(f, " Dispatch\n");
|
|
|
9bac43 |
+ mon(f, " Physical sections\n");
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ for (i = 0; i < d->map.sections_nb; ++i) {
|
|
|
9bac43 |
+ MemoryRegionSection *s = d->map.sections + i;
|
|
|
9bac43 |
+ const char *names[] = { " [unassigned]", " [not dirty]",
|
|
|
9bac43 |
+ " [ROM]", " [watch]" };
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ mon(f, " #%d @" TARGET_FMT_plx ".." TARGET_FMT_plx " %s%s%s%s%s",
|
|
|
9bac43 |
+ i,
|
|
|
9bac43 |
+ s->offset_within_address_space,
|
|
|
9bac43 |
+ s->offset_within_address_space + MR_SIZE(s->mr->size),
|
|
|
9bac43 |
+ s->mr->name ? s->mr->name : "(noname)",
|
|
|
9bac43 |
+ i < ARRAY_SIZE(names) ? names[i] : "",
|
|
|
9bac43 |
+ s->mr == root ? " [ROOT]" : "",
|
|
|
9bac43 |
+ s == d->mru_section ? " [MRU]" : "",
|
|
|
9bac43 |
+ s->mr->is_iommu ? " [iommu]" : "");
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ if (s->mr->alias) {
|
|
|
9bac43 |
+ mon(f, " alias=%s", s->mr->alias->name ?
|
|
|
9bac43 |
+ s->mr->alias->name : "noname");
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+ mon(f, "\n");
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ mon(f, " Nodes (%d bits per level, %d levels) ptr=[%d] skip=%d\n",
|
|
|
9bac43 |
+ P_L2_BITS, P_L2_LEVELS, d->phys_map.ptr, d->phys_map.skip);
|
|
|
9bac43 |
+ for (i = 0; i < d->map.nodes_nb; ++i) {
|
|
|
9bac43 |
+ int j, jprev;
|
|
|
9bac43 |
+ PhysPageEntry prev;
|
|
|
9bac43 |
+ Node *n = d->map.nodes + i;
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ mon(f, " [%d]\n", i);
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ for (j = 0, jprev = 0, prev = *n[0]; j < ARRAY_SIZE(*n); ++j) {
|
|
|
9bac43 |
+ PhysPageEntry *pe = *n + j;
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ if (pe->ptr == prev.ptr && pe->skip == prev.skip) {
|
|
|
9bac43 |
+ continue;
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ mtree_print_phys_entries(mon, f, jprev, j, prev.skip, prev.ptr);
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ jprev = j;
|
|
|
9bac43 |
+ prev = *pe;
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ if (jprev != ARRAY_SIZE(*n)) {
|
|
|
9bac43 |
+ mtree_print_phys_entries(mon, f, jprev, j, prev.skip, prev.ptr);
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+}
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+#endif
|
|
|
9bac43 |
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
|
|
|
9bac43 |
index 0967e41..30b335f 100644
|
|
|
9bac43 |
--- a/hmp-commands-info.hx
|
|
|
9bac43 |
+++ b/hmp-commands-info.hx
|
|
|
9bac43 |
@@ -253,9 +253,10 @@ ETEXI
|
|
|
9bac43 |
|
|
|
9bac43 |
{
|
|
|
9bac43 |
.name = "mtree",
|
|
|
9bac43 |
- .args_type = "flatview:-f",
|
|
|
9bac43 |
- .params = "[-f]",
|
|
|
9bac43 |
- .help = "show memory tree (-f: dump flat view for address spaces)",
|
|
|
9bac43 |
+ .args_type = "flatview:-f,dispatch_tree:-d",
|
|
|
9bac43 |
+ .params = "[-f][-d]",
|
|
|
9bac43 |
+ .help = "show memory tree (-f: dump flat view for address spaces;"
|
|
|
9bac43 |
+ "-d: dump dispatch tree, valid with -f only)",
|
|
|
9bac43 |
.cmd = hmp_info_mtree,
|
|
|
9bac43 |
},
|
|
|
9bac43 |
|
|
|
9bac43 |
diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h
|
|
|
9bac43 |
index d4a35c6..647e9bd 100644
|
|
|
9bac43 |
--- a/include/exec/memory-internal.h
|
|
|
9bac43 |
+++ b/include/exec/memory-internal.h
|
|
|
9bac43 |
@@ -35,5 +35,9 @@ AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as);
|
|
|
9bac43 |
AddressSpaceDispatch *flatview_to_dispatch(FlatView *fv);
|
|
|
9bac43 |
void address_space_dispatch_free(AddressSpaceDispatch *d);
|
|
|
9bac43 |
|
|
|
9bac43 |
+void mtree_print_dispatch(fprintf_function mon, void *f,
|
|
|
9bac43 |
+ struct AddressSpaceDispatch *d,
|
|
|
9bac43 |
+ MemoryRegion *root);
|
|
|
9bac43 |
+
|
|
|
9bac43 |
#endif
|
|
|
9bac43 |
#endif
|
|
|
9bac43 |
diff --git a/include/exec/memory.h b/include/exec/memory.h
|
|
|
9bac43 |
index 6715551..157eae6 100644
|
|
|
9bac43 |
--- a/include/exec/memory.h
|
|
|
9bac43 |
+++ b/include/exec/memory.h
|
|
|
9bac43 |
@@ -1525,7 +1525,8 @@ void memory_global_dirty_log_start(void);
|
|
|
9bac43 |
*/
|
|
|
9bac43 |
void memory_global_dirty_log_stop(void);
|
|
|
9bac43 |
|
|
|
9bac43 |
-void mtree_info(fprintf_function mon_printf, void *f, bool flatview);
|
|
|
9bac43 |
+void mtree_info(fprintf_function mon_printf, void *f, bool flatview,
|
|
|
9bac43 |
+ bool dispatch_tree);
|
|
|
9bac43 |
|
|
|
9bac43 |
/**
|
|
|
9bac43 |
* memory_region_request_mmio_ptr: request a pointer to an mmio
|
|
|
9bac43 |
diff --git a/memory.c b/memory.c
|
|
|
9bac43 |
index 6914d87..25a8bf2 100644
|
|
|
9bac43 |
--- a/memory.c
|
|
|
9bac43 |
+++ b/memory.c
|
|
|
9bac43 |
@@ -2906,18 +2906,44 @@ static void mtree_print_mr(fprintf_function mon_printf, void *f,
|
|
|
9bac43 |
}
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
-static void mtree_print_flatview(fprintf_function p, void *f,
|
|
|
9bac43 |
- AddressSpace *as)
|
|
|
9bac43 |
+struct FlatViewInfo {
|
|
|
9bac43 |
+ fprintf_function mon_printf;
|
|
|
9bac43 |
+ void *f;
|
|
|
9bac43 |
+ int counter;
|
|
|
9bac43 |
+ bool dispatch_tree;
|
|
|
9bac43 |
+};
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+static void mtree_print_flatview(gpointer key, gpointer value,
|
|
|
9bac43 |
+ gpointer user_data)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
- FlatView *view = address_space_get_flatview(as);
|
|
|
9bac43 |
+ FlatView *view = key;
|
|
|
9bac43 |
+ GArray *fv_address_spaces = value;
|
|
|
9bac43 |
+ struct FlatViewInfo *fvi = user_data;
|
|
|
9bac43 |
+ fprintf_function p = fvi->mon_printf;
|
|
|
9bac43 |
+ void *f = fvi->f;
|
|
|
9bac43 |
FlatRange *range = &view->ranges[0];
|
|
|
9bac43 |
MemoryRegion *mr;
|
|
|
9bac43 |
int n = view->nr;
|
|
|
9bac43 |
+ int i;
|
|
|
9bac43 |
+ AddressSpace *as;
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ p(f, "FlatView #%d\n", fvi->counter);
|
|
|
9bac43 |
+ ++fvi->counter;
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ for (i = 0; i < fv_address_spaces->len; ++i) {
|
|
|
9bac43 |
+ as = g_array_index(fv_address_spaces, AddressSpace*, i);
|
|
|
9bac43 |
+ p(f, " AS \"%s\", root: %s", as->name, memory_region_name(as->root));
|
|
|
9bac43 |
+ if (as->root->alias) {
|
|
|
9bac43 |
+ p(f, ", alias %s", memory_region_name(as->root->alias));
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+ p(f, "\n");
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ p(f, " Root memory region: %s\n",
|
|
|
9bac43 |
+ view->root ? memory_region_name(view->root) : "(none)");
|
|
|
9bac43 |
|
|
|
9bac43 |
if (n <= 0) {
|
|
|
9bac43 |
- p(f, MTREE_INDENT "No rendered FlatView for "
|
|
|
9bac43 |
- "address space '%s'\n", as->name);
|
|
|
9bac43 |
- flatview_unref(view);
|
|
|
9bac43 |
+ p(f, MTREE_INDENT "No rendered FlatView\n\n");
|
|
|
9bac43 |
return;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
@@ -2944,21 +2970,65 @@ static void mtree_print_flatview(fprintf_function p, void *f,
|
|
|
9bac43 |
range++;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
+#if !defined(CONFIG_USER_ONLY)
|
|
|
9bac43 |
+ if (fvi->dispatch_tree && view->root) {
|
|
|
9bac43 |
+ mtree_print_dispatch(p, f, view->dispatch, view->root);
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+#endif
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ p(f, "\n");
|
|
|
9bac43 |
+}
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+static gboolean mtree_info_flatview_free(gpointer key, gpointer value,
|
|
|
9bac43 |
+ gpointer user_data)
|
|
|
9bac43 |
+{
|
|
|
9bac43 |
+ FlatView *view = key;
|
|
|
9bac43 |
+ GArray *fv_address_spaces = value;
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ g_array_unref(fv_address_spaces);
|
|
|
9bac43 |
flatview_unref(view);
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ return true;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
-void mtree_info(fprintf_function mon_printf, void *f, bool flatview)
|
|
|
9bac43 |
+void mtree_info(fprintf_function mon_printf, void *f, bool flatview,
|
|
|
9bac43 |
+ bool dispatch_tree)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
MemoryRegionListHead ml_head;
|
|
|
9bac43 |
MemoryRegionList *ml, *ml2;
|
|
|
9bac43 |
AddressSpace *as;
|
|
|
9bac43 |
|
|
|
9bac43 |
if (flatview) {
|
|
|
9bac43 |
+ FlatView *view;
|
|
|
9bac43 |
+ struct FlatViewInfo fvi = {
|
|
|
9bac43 |
+ .mon_printf = mon_printf,
|
|
|
9bac43 |
+ .f = f,
|
|
|
9bac43 |
+ .counter = 0,
|
|
|
9bac43 |
+ .dispatch_tree = dispatch_tree
|
|
|
9bac43 |
+ };
|
|
|
9bac43 |
+ GArray *fv_address_spaces;
|
|
|
9bac43 |
+ GHashTable *views = g_hash_table_new(g_direct_hash, g_direct_equal);
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ /* Gather all FVs in one table */
|
|
|
9bac43 |
QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
|
|
|
9bac43 |
- mon_printf(f, "address-space (flat view): %s\n", as->name);
|
|
|
9bac43 |
- mtree_print_flatview(mon_printf, f, as);
|
|
|
9bac43 |
- mon_printf(f, "\n");
|
|
|
9bac43 |
+ view = address_space_get_flatview(as);
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ fv_address_spaces = g_hash_table_lookup(views, view);
|
|
|
9bac43 |
+ if (!fv_address_spaces) {
|
|
|
9bac43 |
+ fv_address_spaces = g_array_new(false, false, sizeof(as));
|
|
|
9bac43 |
+ g_hash_table_insert(views, view, fv_address_spaces);
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ g_array_append_val(fv_address_spaces, as);
|
|
|
9bac43 |
}
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ /* Print */
|
|
|
9bac43 |
+ g_hash_table_foreach(views, mtree_print_flatview, &fvi);
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ /* Free */
|
|
|
9bac43 |
+ g_hash_table_foreach_remove(views, mtree_info_flatview_free, 0);
|
|
|
9bac43 |
+ g_hash_table_unref(views);
|
|
|
9bac43 |
+
|
|
|
9bac43 |
return;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
diff --git a/monitor.c b/monitor.c
|
|
|
9bac43 |
index c0a8dbc..6380e4a 100644
|
|
|
9bac43 |
--- a/monitor.c
|
|
|
9bac43 |
+++ b/monitor.c
|
|
|
9bac43 |
@@ -1734,8 +1734,9 @@ static void hmp_boot_set(Monitor *mon, const QDict *qdict)
|
|
|
9bac43 |
static void hmp_info_mtree(Monitor *mon, const QDict *qdict)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
bool flatview = qdict_get_try_bool(qdict, "flatview", false);
|
|
|
9bac43 |
+ bool dispatch_tree = qdict_get_try_bool(qdict, "dispatch_tree", false);
|
|
|
9bac43 |
|
|
|
9bac43 |
- mtree_info((fprintf_function)monitor_printf, mon, flatview);
|
|
|
9bac43 |
+ mtree_info((fprintf_function)monitor_printf, mon, flatview, dispatch_tree);
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
static void hmp_info_numa(Monitor *mon, const QDict *qdict)
|
|
|
9bac43 |
--
|
|
|
9bac43 |
1.8.3.1
|
|
|
9bac43 |
|