Blame SOURCES/kvm-memory-Rework-info-mtree-to-print-flat-views-and-dis.patch

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