qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2] memory: simple memory tree printer
@ 2011-09-17 19:27 Blue Swirl
  2011-09-18 12:57 ` Jan Kiszka
  2011-09-18 13:53 ` Avi Kivity
  0 siblings, 2 replies; 9+ messages in thread
From: Blue Swirl @ 2011-09-17 19:27 UTC (permalink / raw)
  To: qemu-devel

Add a monitor command 'info mtree' to show the memory hierarchy
much like /proc/iomem in Linux.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
v1->v2: use /proc/iomem format.
---
 memory.c  |   27 +++++++++++++++++++++++++++
 memory.h  |    2 ++
 monitor.c |    7 +++++++
 3 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/memory.c b/memory.c
index 101b67c..275f5cf 100644
--- a/memory.c
+++ b/memory.c
@@ -17,6 +17,7 @@
 #include "bitops.h"
 #include "kvm.h"
 #include <assert.h>
+#include "monitor.h"

 unsigned memory_region_transaction_depth = 0;

@@ -1253,3 +1254,29 @@ void set_system_io_map(MemoryRegion *mr)
     address_space_io.root = mr;
     memory_region_update_topology();
 }
+
+static void mtree_print_mr(Monitor *mon, MemoryRegion *mr, unsigned int level)
+{
+    MemoryRegion *submr;
+    unsigned int i;
+
+    for (i = 0; i < level; i++) {
+        monitor_printf(mon, "  ");
+    }
+    monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " : %s\n",
+                   mr->addr, mr->addr + (target_phys_addr_t)mr->size - 1,
+                   mr->name);
+
+    QTAILQ_FOREACH(submr, &mr->subregions, subregions_link) {
+        mtree_print_mr(mon, submr, level + 1);
+    }
+}
+
+void mtree_info(Monitor *mon)
+{
+    monitor_printf(mon, "memory\n");
+    mtree_print_mr(mon, address_space_memory.root, 0);
+
+    monitor_printf(mon, "I/O\n");
+    mtree_print_mr(mon, address_space_io.root, 0);
+}
diff --git a/memory.h b/memory.h
index 06b83ae..09d8e29 100644
--- a/memory.h
+++ b/memory.h
@@ -500,6 +500,8 @@ void memory_region_transaction_begin(void);
  */
 void memory_region_transaction_commit(void);

+void mtree_info(Monitor *mon);
+
 #endif

 #endif
diff --git a/monitor.c b/monitor.c
index 03ae997..0302446 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2968,6 +2968,13 @@ static const mon_cmd_t info_cmds[] = {
     },
 #endif
     {
+        .name       = "mtree",
+        .args_type  = "",
+        .params     = "",
+        .help       = "show memory tree",
+        .mhandler.info = mtree_info,
+    },
+    {
         .name       = "jit",
         .args_type  = "",
         .params     = "",
-- 
1.6.2.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH v2] memory: simple memory tree printer
  2011-09-17 19:27 [Qemu-devel] [PATCH v2] memory: simple memory tree printer Blue Swirl
@ 2011-09-18 12:57 ` Jan Kiszka
  2011-09-18 13:53 ` Avi Kivity
  1 sibling, 0 replies; 9+ messages in thread
From: Jan Kiszka @ 2011-09-18 12:57 UTC (permalink / raw)
  To: Blue Swirl; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1363 bytes --]

On 2011-09-17 21:27, Blue Swirl wrote:
> Add a monitor command 'info mtree' to show the memory hierarchy
> much like /proc/iomem in Linux.
> 
> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
> ---
> v1->v2: use /proc/iomem format.
> ---
>  memory.c  |   27 +++++++++++++++++++++++++++
>  memory.h  |    2 ++
>  monitor.c |    7 +++++++
>  3 files changed, 36 insertions(+), 0 deletions(-)
> 
> diff --git a/memory.c b/memory.c
> index 101b67c..275f5cf 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -17,6 +17,7 @@
>  #include "bitops.h"
>  #include "kvm.h"
>  #include <assert.h>
> +#include "monitor.h"
> 
>  unsigned memory_region_transaction_depth = 0;
> 
> @@ -1253,3 +1254,29 @@ void set_system_io_map(MemoryRegion *mr)
>      address_space_io.root = mr;
>      memory_region_update_topology();
>  }
> +
> +static void mtree_print_mr(Monitor *mon, MemoryRegion *mr, unsigned int level)
> +{
> +    MemoryRegion *submr;
> +    unsigned int i;
> +
> +    for (i = 0; i < level; i++) {
> +        monitor_printf(mon, "  ");
> +    }
> +    monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " : %s\n",
> +                   mr->addr, mr->addr + (target_phys_addr_t)mr->size - 1,
> +                   mr->name);

I would prefer absolute addresses here. And the priority field needs to
be dumped as well.

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH v2] memory: simple memory tree printer
  2011-09-17 19:27 [Qemu-devel] [PATCH v2] memory: simple memory tree printer Blue Swirl
  2011-09-18 12:57 ` Jan Kiszka
@ 2011-09-18 13:53 ` Avi Kivity
  2011-09-18 14:07   ` Blue Swirl
  1 sibling, 1 reply; 9+ messages in thread
From: Avi Kivity @ 2011-09-18 13:53 UTC (permalink / raw)
  To: Blue Swirl; +Cc: qemu-devel

On 09/17/2011 10:27 PM, Blue Swirl wrote:
> Add a monitor command 'info mtree' to show the memory hierarchy
> much like /proc/iomem in Linux.
>
>

Still missing alias support.  PCI would be invisible on a PC (or any 
machine which has PCI holes implemented properly).

Maybe we need to dump both the memory tree and the flat view - the 
memory tree for the logical hierarchy and the flat view to see what 
actually happens (I have an address, where does it go?)

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH v2] memory: simple memory tree printer
  2011-09-18 13:53 ` Avi Kivity
@ 2011-09-18 14:07   ` Blue Swirl
  2011-09-18 14:26     ` Avi Kivity
  0 siblings, 1 reply; 9+ messages in thread
From: Blue Swirl @ 2011-09-18 14:07 UTC (permalink / raw)
  To: Avi Kivity; +Cc: qemu-devel

On Sun, Sep 18, 2011 at 1:53 PM, Avi Kivity <avi@redhat.com> wrote:
> On 09/17/2011 10:27 PM, Blue Swirl wrote:
>>
>> Add a monitor command 'info mtree' to show the memory hierarchy
>> much like /proc/iomem in Linux.
>>
>>
>
> Still missing alias support.  PCI would be invisible on a PC (or any machine
> which has PCI holes implemented properly).

Yes, that annoyed me too when debugging the PPC patch. But how should
that look like? Consider for example that in the PPC case, range 0 to
0x80000000 is RAM from CPU point of view but only PCI MMIO space when
looking after the PCI bridge. I/O shouldn't need separate handling if
the CPU does not have PIO instructions, but instead PIO space is
mapped as MMIO as on Sparc64 and PPC. I/O should be visible there.

> Maybe we need to dump both the memory tree and the flat view - the memory
> tree for the logical hierarchy and the flat view to see what actually
> happens (I have an address, where does it go?)

I have some trouble thinking about how to print fully converted,
per-CPU memory trees. Also, if the memory API is fully embraced and
extended to handle DMA and IOMMUs, each device could have a different
view on the system memory. Perhaps the tool should take a device ID
(also CPU ID) as a parameter to give it a starting point.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH v2] memory: simple memory tree printer
  2011-09-18 14:07   ` Blue Swirl
@ 2011-09-18 14:26     ` Avi Kivity
  0 siblings, 0 replies; 9+ messages in thread
From: Avi Kivity @ 2011-09-18 14:26 UTC (permalink / raw)
  To: Blue Swirl; +Cc: qemu-devel

On 09/18/2011 05:07 PM, Blue Swirl wrote:
> On Sun, Sep 18, 2011 at 1:53 PM, Avi Kivity<avi@redhat.com>  wrote:
> >  On 09/17/2011 10:27 PM, Blue Swirl wrote:
> >>
> >>  Add a monitor command 'info mtree' to show the memory hierarchy
> >>  much like /proc/iomem in Linux.
> >>
> >>
> >
> >  Still missing alias support.  PCI would be invisible on a PC (or any machine
> >  which has PCI holes implemented properly).
>
> Yes, that annoyed me too when debugging the PPC patch. But how should
> that look like? Consider for example that in the PPC case, range 0 to
> 0x80000000 is RAM from CPU point of view but only PCI MMIO space when
> looking after the PCI bridge. I/O shouldn't need separate handling if
> the CPU does not have PIO instructions, but instead PIO space is
> mapped as MMIO as on Sparc64 and PPC. I/O should be visible there.

Have some notation for a reference.  Example for PC:

Memory:
00000000-7fffffffffffffff system-memory container
   00000000-0009ffff alias @ram 00000000-0009ffff
   000a0000-000bffff alias @pci 000a0000-000bffff
   ...
   e0000000-ffffffff alias @pci e0000000-ffffffff

pci:
00000000-ffffffffff pci container
   000a0000-000bffff alias @vgam 00000000-0001ffff
   e0000000-e1ffffff alias @vram 00000000-01ffffff
   e2000000-e2001000 e1000-mmio

vram:
00000000-01ffffff vram ram

(each time you encounter a new alias target, add it to the print queue, 
it should work itself out naturally)

>
> >  Maybe we need to dump both the memory tree and the flat view - the memory
> >  tree for the logical hierarchy and the flat view to see what actually
> >  happens (I have an address, where does it go?)
>
> I have some trouble thinking about how to print fully converted,
> per-CPU memory trees. Also, if the memory API is fully embraced and
> extended to handle DMA and IOMMUs, each device could have a different
> view on the system memory. Perhaps the tool should take a device ID
> (also CPU ID) as a parameter to give it a starting point.

The possibilities are endless.

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH v2] memory: simple memory tree printer
  2011-09-26  9:45 ` Avi Kivity
@ 2011-09-26 17:13   ` Blue Swirl
  0 siblings, 0 replies; 9+ messages in thread
From: Blue Swirl @ 2011-09-26 17:13 UTC (permalink / raw)
  To: Avi Kivity; +Cc: qemu-devel

On Mon, Sep 26, 2011 at 9:45 AM, Avi Kivity <avi@redhat.com> wrote:
> On 09/25/2011 11:19 PM, Blue Swirl wrote:
>>
>> Add a monitor command 'info mtree' to show the memory hierarchy
>> much like /proc/iomem in Linux.
>>
>>
>> diff --git a/memory.c b/memory.c
>> index ba74435..6b33fc4 100644
>> --- a/memory.c
>> +++ b/memory.c
>> @@ -17,6 +17,7 @@
>>  #include "bitops.h"
>>  #include "kvm.h"
>>  #include<assert.h>
>> +#include "monitor.h"
>
> This is a unfortunate - now the monitor and memory.c are interdependent;
> this makes it harder to write unit tests (at least without ifdefs).
>
> I guess we can disentangle it later using some kind of generic walker.

monitor.c could pass a pointer to a fprintf-like function and a void
*opaque for Monitor *mon.

>>  unsigned memory_region_transaction_depth = 0;
>>
>> @@ -1256,3 +1257,103 @@ void set_system_io_map(MemoryRegion *mr)
>>      address_space_io.root = mr;
>>      memory_region_update_topology();
>>  }
>> +
>> +typedef struct MemoryRegionList MemoryRegionList;
>> +typedef struct MemoryRegionListHead MemoryRegionListHead;
>> +
>> +struct MemoryRegionList {
>> +    const MemoryRegion *mr;
>> +    QLIST_ENTRY(MemoryRegionList) queue;
>> +};
>> +
>> +struct MemoryRegionListHead {
>> +    QLIST_HEAD(queue, MemoryRegionList) head;
>> +};
>
> Straight typedef of QLIST_HEAD(queue, MemoryRegionList) would be nicer.

OK.

>> +
>> +static void mtree_print_mr(Monitor *mon, const MemoryRegion *mr,
>> +                           unsigned int level, target_phys_addr_t base,
>> +                           MemoryRegionListHead *print_queue)
>> +{
>> +    const MemoryRegion *submr;
>> +    unsigned int i;
>> +
>> +    for (i = 0; i<  level; i++) {
>> +        monitor_printf(mon, "  ");
>> +    }
>> +
>> +    if (mr->alias) {
>> +        if (print_queue) {
>
> print_queue is never NULL, why test?

Leftover from previous version. I'll remove the test.

>> +            MemoryRegionList *ml;
>> +            bool found = false;
>> +
>> +            /* check if the alias is already in the queue */
>> +            QLIST_FOREACH(ml,&print_queue->head, queue) {
>> +                if (ml->mr == mr->alias) {
>> +                    found = true;
>> +                }
>> +            }
>> +
>> +            if (!found) {
>> +                ml = g_malloc(sizeof(*ml));
>> +                ml->mr = mr->alias;
>> +                QLIST_INSERT_HEAD(&print_queue->head, ml, queue);
>> +            }
>> +        }
>> +        monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " :
>> alias %s @%s "
>> +                       TARGET_FMT_plx "-" TARGET_FMT_plx "\n",
>> +                       base + mr->addr,
>> +                       base + mr->addr + (target_phys_addr_t)mr->size -
>> 1,
>> +                       mr->name,
>> +                       mr->alias->name,
>> +                       mr->alias_offset + mr->alias->addr,
>> +                       mr->alias_offset  + mr->alias->addr +
>> +                       (target_phys_addr_t)mr->size - 1);
>
> Adding mr->alias->addr doesn't help much - it doesn't give you an absolute
> address, just relative to the alias target's container.  If it's deep enough
> in the tree the address is meaningless.

Right, it looked a bit nicer this way but I'll remove that.

>> +
>> +    } else {
>> +        monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " : %s\n",
>> +                       base + mr->addr,
>> +                       base + mr->addr + (target_phys_addr_t)mr->size -
>> 1,
>> +                       mr->name);
>> +    }
>> +    QTAILQ_FOREACH(submr,&mr->subregions, subregions_link) {
>> +        mtree_print_mr(mon, submr, level + 1, base + mr->addr,
>> print_queue);
>> +    }
>> +}
>> +
>> +void mtree_info(Monitor *mon)
>> +{
>> +    MemoryRegionListHead *ml_head, *ml_head2, *ml_tmp;
>> +    MemoryRegionList *ml, *ml2;
>> +
>> +    ml_head = g_malloc(sizeof(*ml));
>
> Wrong type.  g_new() is much better for this.
>
>> +    QLIST_INIT(&ml_head->head);
>> +
>> +    monitor_printf(mon, "memory\n");
>> +    mtree_print_mr(mon, address_space_memory.root, 0, 0, ml_head);
>> +
>> +    ml_head2 = g_malloc(sizeof(*ml));
>
> Again.

OK for both.

>> +
>> +    /* print aliased regions */
>> +    for (;;) {
>> +        QLIST_INIT(&ml_head2->head);
>> +
>> +        QLIST_FOREACH_SAFE(ml,&ml_head->head, queue, ml2) {
>> +            monitor_printf(mon, "%s\n", ml->mr->name);
>> +            mtree_print_mr(mon, ml->mr, 0, 0, ml_head2);
>> +            g_free(ml);
>> +        }
>
> I think you can eliminate more duplicates by adding a bool ->printed to the
> queue entry, and always using the same queue.  Iterate until no un ->printed
> elements remain.

Good idea, that could avoid the forever loop.

>> +        if (QLIST_EMPTY(&ml_head->head)) {
>> +            break;
>> +        }
>> +        ml_tmp = ml_head;
>> +        ml_head = ml_head2;
>> +        ml_head2 = ml_tmp;
>> +    }
>> +
>> +#ifdef TARGET_I386
>> +    monitor_printf(mon, "I/O\n");
>> +    mtree_print_mr(mon, address_space_io.root, 0, 0, ml_head);
>> +#endif
>> +    g_free(ml_head2);
>> +    g_free(ml_head);
>> +}
>> diff --git a/memory.h b/memory.h
>> index 06b83ae..09d8e29 100644
>> --- a/memory.h
>> +++ b/memory.h
>> @@ -500,6 +500,8 @@ void memory_region_transaction_begin(void);
>>   */
>>  void memory_region_transaction_commit(void);
>>
>> +void mtree_info(Monitor *mon);
>> +
>>  #endif
>>
>
> --
> error compiling committee.c: too many arguments to function
>
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH v2] memory: simple memory tree printer
  2011-09-25 20:19 Blue Swirl
  2011-09-26  8:07 ` Wayne Xia
@ 2011-09-26  9:45 ` Avi Kivity
  2011-09-26 17:13   ` Blue Swirl
  1 sibling, 1 reply; 9+ messages in thread
From: Avi Kivity @ 2011-09-26  9:45 UTC (permalink / raw)
  To: Blue Swirl; +Cc: qemu-devel

On 09/25/2011 11:19 PM, Blue Swirl wrote:
> Add a monitor command 'info mtree' to show the memory hierarchy
> much like /proc/iomem in Linux.
>
>
> diff --git a/memory.c b/memory.c
> index ba74435..6b33fc4 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -17,6 +17,7 @@
>   #include "bitops.h"
>   #include "kvm.h"
>   #include<assert.h>
> +#include "monitor.h"

This is a unfortunate - now the monitor and memory.c are interdependent; 
this makes it harder to write unit tests (at least without ifdefs).

I guess we can disentangle it later using some kind of generic walker.

>   unsigned memory_region_transaction_depth = 0;
>
> @@ -1256,3 +1257,103 @@ void set_system_io_map(MemoryRegion *mr)
>       address_space_io.root = mr;
>       memory_region_update_topology();
>   }
> +
> +typedef struct MemoryRegionList MemoryRegionList;
> +typedef struct MemoryRegionListHead MemoryRegionListHead;
> +
> +struct MemoryRegionList {
> +    const MemoryRegion *mr;
> +    QLIST_ENTRY(MemoryRegionList) queue;
> +};
> +
> +struct MemoryRegionListHead {
> +    QLIST_HEAD(queue, MemoryRegionList) head;
> +};

Straight typedef of QLIST_HEAD(queue, MemoryRegionList) would be nicer.

> +
> +static void mtree_print_mr(Monitor *mon, const MemoryRegion *mr,
> +                           unsigned int level, target_phys_addr_t base,
> +                           MemoryRegionListHead *print_queue)
> +{
> +    const MemoryRegion *submr;
> +    unsigned int i;
> +
> +    for (i = 0; i<  level; i++) {
> +        monitor_printf(mon, "  ");
> +    }
> +
> +    if (mr->alias) {
> +        if (print_queue) {

print_queue is never NULL, why test?


> +            MemoryRegionList *ml;
> +            bool found = false;
> +
> +            /* check if the alias is already in the queue */
> +            QLIST_FOREACH(ml,&print_queue->head, queue) {
> +                if (ml->mr == mr->alias) {
> +                    found = true;
> +                }
> +            }
> +
> +            if (!found) {
> +                ml = g_malloc(sizeof(*ml));
> +                ml->mr = mr->alias;
> +                QLIST_INSERT_HEAD(&print_queue->head, ml, queue);
> +            }
> +        }
> +        monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " :
> alias %s @%s "
> +                       TARGET_FMT_plx "-" TARGET_FMT_plx "\n",
> +                       base + mr->addr,
> +                       base + mr->addr + (target_phys_addr_t)mr->size - 1,
> +                       mr->name,
> +                       mr->alias->name,
> +                       mr->alias_offset + mr->alias->addr,
> +                       mr->alias_offset  + mr->alias->addr +
> +                       (target_phys_addr_t)mr->size - 1);

Adding mr->alias->addr doesn't help much - it doesn't give you an 
absolute address, just relative to the alias target's container.  If 
it's deep enough in the tree the address is meaningless.

> +
> +    } else {
> +        monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " : %s\n",
> +                       base + mr->addr,
> +                       base + mr->addr + (target_phys_addr_t)mr->size - 1,
> +                       mr->name);
> +    }
> +    QTAILQ_FOREACH(submr,&mr->subregions, subregions_link) {
> +        mtree_print_mr(mon, submr, level + 1, base + mr->addr, print_queue);
> +    }
> +}
> +
> +void mtree_info(Monitor *mon)
> +{
> +    MemoryRegionListHead *ml_head, *ml_head2, *ml_tmp;
> +    MemoryRegionList *ml, *ml2;
> +
> +    ml_head = g_malloc(sizeof(*ml));

Wrong type.  g_new() is much better for this.

> +    QLIST_INIT(&ml_head->head);
> +
> +    monitor_printf(mon, "memory\n");
> +    mtree_print_mr(mon, address_space_memory.root, 0, 0, ml_head);
> +
> +    ml_head2 = g_malloc(sizeof(*ml));

Again.

> +
> +    /* print aliased regions */
> +    for (;;) {
> +        QLIST_INIT(&ml_head2->head);
> +
> +        QLIST_FOREACH_SAFE(ml,&ml_head->head, queue, ml2) {
> +            monitor_printf(mon, "%s\n", ml->mr->name);
> +            mtree_print_mr(mon, ml->mr, 0, 0, ml_head2);
> +            g_free(ml);
> +        }

I think you can eliminate more duplicates by adding a bool ->printed to 
the queue entry, and always using the same queue.  Iterate until no un 
->printed elements remain.

> +        if (QLIST_EMPTY(&ml_head->head)) {
> +            break;
> +        }
> +        ml_tmp = ml_head;
> +        ml_head = ml_head2;
> +        ml_head2 = ml_tmp;
> +    }
> +
> +#ifdef TARGET_I386
> +    monitor_printf(mon, "I/O\n");
> +    mtree_print_mr(mon, address_space_io.root, 0, 0, ml_head);
> +#endif
> +    g_free(ml_head2);
> +    g_free(ml_head);
> +}
> diff --git a/memory.h b/memory.h
> index 06b83ae..09d8e29 100644
> --- a/memory.h
> +++ b/memory.h
> @@ -500,6 +500,8 @@ void memory_region_transaction_begin(void);
>    */
>   void memory_region_transaction_commit(void);
>
> +void mtree_info(Monitor *mon);
> +
>   #endif
>

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH v2] memory: simple memory tree printer
  2011-09-25 20:19 Blue Swirl
@ 2011-09-26  8:07 ` Wayne Xia
  2011-09-26  9:45 ` Avi Kivity
  1 sibling, 0 replies; 9+ messages in thread
From: Wayne Xia @ 2011-09-26  8:07 UTC (permalink / raw)
  To: qemu-devel

Tried it, good tool to inspect guest memory layout.
It would be more nice if some symbol could be used to show
hierarchies.

0000000000000000-7ffffffffffffffe : pci
|__00000000feba0000-00000000febbffff : e1000-mmio
|__00000000febf0000-00000000febf0fff : cirrus-mmio
|__000000fc000000-00000000fdffffff : cirrus-pci-bar0
    |__00000000fc000000-00000000fc7fffff : vga.vram


于 2011-9-26 4:19, Blue Swirl 写道:
> Add a monitor command 'info mtree' to show the memory hierarchy
> much like /proc/iomem in Linux.
>
> Signed-off-by: Blue Swirl<blauwirbel@gmail.com>
> ---
> i386:
> memory
> 0000000000000000-7ffffffffffffffe : system
>    00000000000ec000-00000000000effff : alias pam-ram @pc.ram
> 00000000000ec000-00000000000effff
>    00000000000e8000-00000000000ebfff : alias pam-ram @pc.ram
> 00000000000e8000-00000000000ebfff
>    00000000000e4000-00000000000e7fff : alias pam-ram @pc.ram
> 00000000000e4000-00000000000e7fff
>    00000000000e0000-00000000000e3fff : alias pam-ram @pc.ram
> 00000000000e0000-00000000000e3fff
>    00000000000dc000-00000000000dffff : alias pam-ram @pc.ram
> 00000000000dc000-00000000000dffff
>    00000000000d8000-00000000000dbfff : alias pam-ram @pc.ram
> 00000000000d8000-00000000000dbfff
>    00000000000d4000-00000000000d7fff : alias pam-ram @pc.ram
> 00000000000d4000-00000000000d7fff
>    00000000000d0000-00000000000d3fff : alias pam-ram @pc.ram
> 00000000000d0000-00000000000d3fff
>    00000000000cc000-00000000000cffff : alias pam-ram @pc.ram
> 00000000000cc000-00000000000cffff
>    00000000000c8000-00000000000cbfff : alias pam-rom @pc.ram
> 00000000000c8000-00000000000cbfff
>    00000000000c4000-00000000000c7fff : alias pam-rom @pc.ram
> 00000000000c4000-00000000000c7fff
>    00000000000c0000-00000000000c3fff : alias pam-rom @pc.ram
> 00000000000c0000-00000000000c3fff
>    00000000000f0000-00000000000fffff : alias pam-rom @pc.ram
> 00000000000f0000-00000000000fffff
>    00000000000a0000-00000000000bffff : alias smram-region @pci
> 00000000000a0000-00000000000bffff
>    4000000000000000-7fffffffffffffff : alias pci-hole64 @pci
> 4000000000000000-7fffffffffffffff
>    0000000008000000-00000000ffffffff : alias pci-hole @pci
> 0000000008000000-00000000ffffffff
>    0000000000000000-0000000007ffffff : alias ram-below-4g @pc.ram
> 0000000000000000-0000000007ffffff
>    00000000fee00000-00000000feefffff : apic
> pci
> 0000000000000000-7ffffffffffffffe : pci
>    00000000feba0000-00000000febbffff : e1000-mmio
>    00000000febf0000-00000000febf0fff : cirrus-mmio
>    00000000fc000000-00000000fdffffff : cirrus-pci-bar0
>      00000000fc000000-00000000fc7fffff : vga.vram
>      00000000fd000000-00000000fd3fffff : cirrus-bitblt-mmio
>      00000000fc000000-00000000fc7fffff : cirrus-linear-io
>    00000000000a0000-00000000000bffff : cirrus-lowmem-container
>      00000000000a0000-00000000000bffff : cirrus-low-memory
>    00000000000c0000-00000000000dffff : pc.rom
>    00000000000e0000-00000000000fffff : alias isa-bios @pc.bios
> 00000000fffe0000-00000000ffffffff
>    00000000fffe0000-00000000ffffffff : pc.bios
> pc.ram
> 0000000000000000-0000000007ffffff : pc.ram
> pc.bios
> 00000000fffe0000-00000000ffffffff : pc.bios
> I/O
> 0000000000000000-000000000000ffff : io
>    000000000000c000-000000000000c03f : e1000-io
>    000000000000c040-000000000000c04f : piix-bmdma-container
>      000000000000c04c-000000000000c04f : bmdma
>      000000000000c048-000000000000c04b : piix-bmdma
>      000000000000c044-000000000000c047 : bmdma
>      000000000000c040-000000000000c043 : piix-bmdma
>    0000000000000cfc-0000000000000cff : pci-conf-data
>    0000000000000cf8-0000000000000cfb : pci-conf-idx
>
> PPC (HEAD)
> memory
> 00000000-fffffffe : system
>    800a0000-800affff : alias vga.chain4 @vga.vram 80000000-8000ffff
>    80880000-808fffff : macio
>      808e0000-808fffff : macio-nvram
>      808a0000-808a0fff : pmac-ide
>      80896000-80895fff : (null)
>      80893000-8089303f : alias escc-bar @escc 80013000-8001303f
>      80888000-80888fff : dbdma
>      80880000-80880fff : heathrow-pic
>    80800000-8080ffff : vga.rom
>    80000000-807fffff : vga.vram
>    800a0000-800bffff : vga-lowmem
>    80013000-8001303f : escc
>    fee00000-fee00fff : pci-data-idx
>    fec00000-fec00fff : pci-conf-idx
>    fe000000-fe1fffff : isa-mmio
> escc
> 80013000-8001303f : escc
> vga.vram
> 80000000-807fffff : vga.vram
>
> PPC with my pci-hole patch:
> memory
> 00000000-fffffffe : system
>    80013000-8001303f : escc
>    fee00000-fee00fff : pci-data-idx
>    fec00000-fec00fff : pci-conf-idx
>    80000000-fdffffff : alias pci-hole @pci-mmio 80000000-fdffffff
>    fe000000-fe1fffff : isa-mmio
> pci-mmio
> 00000000-ffffffff : pci-mmio
>    000a0000-000affff : alias vga.chain4 @vga.vram 80000000-8000ffff
>    80880000-808fffff : macio
>      808e0000-808fffff : macio-nvram
>      808a0000-808a0fff : pmac-ide
>      80896000-80895fff : (null)
>      80893000-8089303f : alias escc-bar @escc 80013000-8001303f
>      80888000-80888fff : dbdma
>      80880000-80880fff : heathrow-pic
>    80800000-8080ffff : vga.rom
>    80000000-807fffff : vga.vram
>    000a0000-000bffff : vga-lowmem
> escc
> 80013000-8001303f : escc
> vga.vram
> 80000000-807fffff : vga.vram
>
> Sparc64:
> 0000000000000000-7ffffffffffffffe : system
>    000001ff00000000-000001ffffffffff : pci-mmio
>      000001ff000a0000-000001ff000affff : alias vga.chain4 @vga.vram
> 0000000000800000-000000000080ffff
>      000001ff03000000-000001ff037fffff : isa-mmio
>      000001ff02000000-000001ff02ffffff : isa-mmio
>      000001ff01000000-000001ff0100ffff : vga.rom
>      000001ff00800000-000001ff00ffffff : vga.vram
>      000001ff00000000-000001ff000fffff : alias pci_bridge_mem
> @pci_pridge_pci 0000000000000000-00000000000fffff
>      000001ff00000000-000001ff000fffff : alias pci_bridge_pref_mem
> @pci_pridge_pci 0000000000000000-00000000000fffff
>      000001ff00000000-000001ff000fffff : alias pci_bridge_mem
> @pci_pridge_pci 0000000000000000-00000000000fffff
>      000001ff00000000-000001ff000fffff : alias pci_bridge_pref_mem
> @pci_pridge_pci 0000000000000000-00000000000fffff
>      000001ff000a0000-000001ff000bffff : vga-lowmem
>    000001fe02000000-000001fe0200ffff : apb-pci-ioport
>    000001fe01000000-000001fe01ffffff : apb-pci-config
>    000001fe00000000-000001fe0000ffff : apb-config
> pci_pridge_pci
>      ^
> 0000000000000000-7ffffffffffffffe : pci_pridge_pci
> pci_pridge_pci
> 0000000000000000-7ffffffffffffffe : pci_pridge_pci
> vga.vram
> 0000000000800000-0000000000ffffff : vga.vram
>
> ---
>   memory.c  |  101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   memory.h  |    2 +
>   monitor.c |    7 ++++
>   3 files changed, 110 insertions(+), 0 deletions(-)
>
> diff --git a/memory.c b/memory.c
> index ba74435..6b33fc4 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -17,6 +17,7 @@
>   #include "bitops.h"
>   #include "kvm.h"
>   #include<assert.h>
> +#include "monitor.h"
>
>   unsigned memory_region_transaction_depth = 0;
>
> @@ -1256,3 +1257,103 @@ void set_system_io_map(MemoryRegion *mr)
>       address_space_io.root = mr;
>       memory_region_update_topology();
>   }
> +
> +typedef struct MemoryRegionList MemoryRegionList;
> +typedef struct MemoryRegionListHead MemoryRegionListHead;
> +
> +struct MemoryRegionList {
> +    const MemoryRegion *mr;
> +    QLIST_ENTRY(MemoryRegionList) queue;
> +};
> +
> +struct MemoryRegionListHead {
> +    QLIST_HEAD(queue, MemoryRegionList) head;
> +};
> +
> +static void mtree_print_mr(Monitor *mon, const MemoryRegion *mr,
> +                           unsigned int level, target_phys_addr_t base,
> +                           MemoryRegionListHead *print_queue)
> +{
> +    const MemoryRegion *submr;
> +    unsigned int i;
> +
> +    for (i = 0; i<  level; i++) {
> +        monitor_printf(mon, "  ");
> +    }
> +
> +    if (mr->alias) {
> +        if (print_queue) {
> +            MemoryRegionList *ml;
> +            bool found = false;
> +
> +            /* check if the alias is already in the queue */
> +            QLIST_FOREACH(ml,&print_queue->head, queue) {
> +                if (ml->mr == mr->alias) {
> +                    found = true;
> +                }
> +            }
> +
> +            if (!found) {
> +                ml = g_malloc(sizeof(*ml));
> +                ml->mr = mr->alias;
> +                QLIST_INSERT_HEAD(&print_queue->head, ml, queue);
> +            }
> +        }
> +        monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " :
> alias %s @%s "
> +                       TARGET_FMT_plx "-" TARGET_FMT_plx "\n",
> +                       base + mr->addr,
> +                       base + mr->addr + (target_phys_addr_t)mr->size - 1,
> +                       mr->name,
> +                       mr->alias->name,
> +                       mr->alias_offset + mr->alias->addr,
> +                       mr->alias_offset  + mr->alias->addr +
> +                       (target_phys_addr_t)mr->size - 1);
> +
> +    } else {
> +        monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " : %s\n",
> +                       base + mr->addr,
> +                       base + mr->addr + (target_phys_addr_t)mr->size - 1,
> +                       mr->name);
> +    }
> +    QTAILQ_FOREACH(submr,&mr->subregions, subregions_link) {
> +        mtree_print_mr(mon, submr, level + 1, base + mr->addr, print_queue);
> +    }
> +}
> +
> +void mtree_info(Monitor *mon)
> +{
> +    MemoryRegionListHead *ml_head, *ml_head2, *ml_tmp;
> +    MemoryRegionList *ml, *ml2;
> +
> +    ml_head = g_malloc(sizeof(*ml));
> +    QLIST_INIT(&ml_head->head);
> +
> +    monitor_printf(mon, "memory\n");
> +    mtree_print_mr(mon, address_space_memory.root, 0, 0, ml_head);
> +
> +    ml_head2 = g_malloc(sizeof(*ml));
> +
> +    /* print aliased regions */
> +    for (;;) {
> +        QLIST_INIT(&ml_head2->head);
> +
> +        QLIST_FOREACH_SAFE(ml,&ml_head->head, queue, ml2) {
> +            monitor_printf(mon, "%s\n", ml->mr->name);
> +            mtree_print_mr(mon, ml->mr, 0, 0, ml_head2);
> +            g_free(ml);
> +        }
> +        if (QLIST_EMPTY(&ml_head->head)) {
> +            break;
> +        }
> +        ml_tmp = ml_head;
> +        ml_head = ml_head2;
> +        ml_head2 = ml_tmp;
> +    }
> +
> +#ifdef TARGET_I386
> +    monitor_printf(mon, "I/O\n");
> +    mtree_print_mr(mon, address_space_io.root, 0, 0, ml_head);
> +#endif
> +    g_free(ml_head2);
> +    g_free(ml_head);
> +}
> diff --git a/memory.h b/memory.h
> index 06b83ae..09d8e29 100644
> --- a/memory.h
> +++ b/memory.h
> @@ -500,6 +500,8 @@ void memory_region_transaction_begin(void);
>    */
>   void memory_region_transaction_commit(void);
>
> +void mtree_info(Monitor *mon);
> +
>   #endif
>
>   #endif
> diff --git a/monitor.c b/monitor.c
> index 8ec2c5e..f86fff6 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -2978,6 +2978,13 @@ static const mon_cmd_t info_cmds[] = {
>       },
>   #endif
>       {
> +        .name       = "mtree",
> +        .args_type  = "",
> +        .params     = "",
> +        .help       = "show memory tree",
> +        .mhandler.info = mtree_info,
> +    },
> +    {
>           .name       = "jit",
>           .args_type  = "",
>           .params     = "",


-- 
Best Regards

Wayne Xia
mail:xiawenc@linux.vnet.ibm.com
tel:86-010-82450803

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH v2] memory: simple memory tree printer
@ 2011-09-25 20:19 Blue Swirl
  2011-09-26  8:07 ` Wayne Xia
  2011-09-26  9:45 ` Avi Kivity
  0 siblings, 2 replies; 9+ messages in thread
From: Blue Swirl @ 2011-09-25 20:19 UTC (permalink / raw)
  To: qemu-devel, Avi Kivity

[-- Attachment #1: Type: text/plain, Size: 10154 bytes --]

Add a monitor command 'info mtree' to show the memory hierarchy
much like /proc/iomem in Linux.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
i386:
memory
0000000000000000-7ffffffffffffffe : system
  00000000000ec000-00000000000effff : alias pam-ram @pc.ram
00000000000ec000-00000000000effff
  00000000000e8000-00000000000ebfff : alias pam-ram @pc.ram
00000000000e8000-00000000000ebfff
  00000000000e4000-00000000000e7fff : alias pam-ram @pc.ram
00000000000e4000-00000000000e7fff
  00000000000e0000-00000000000e3fff : alias pam-ram @pc.ram
00000000000e0000-00000000000e3fff
  00000000000dc000-00000000000dffff : alias pam-ram @pc.ram
00000000000dc000-00000000000dffff
  00000000000d8000-00000000000dbfff : alias pam-ram @pc.ram
00000000000d8000-00000000000dbfff
  00000000000d4000-00000000000d7fff : alias pam-ram @pc.ram
00000000000d4000-00000000000d7fff
  00000000000d0000-00000000000d3fff : alias pam-ram @pc.ram
00000000000d0000-00000000000d3fff
  00000000000cc000-00000000000cffff : alias pam-ram @pc.ram
00000000000cc000-00000000000cffff
  00000000000c8000-00000000000cbfff : alias pam-rom @pc.ram
00000000000c8000-00000000000cbfff
  00000000000c4000-00000000000c7fff : alias pam-rom @pc.ram
00000000000c4000-00000000000c7fff
  00000000000c0000-00000000000c3fff : alias pam-rom @pc.ram
00000000000c0000-00000000000c3fff
  00000000000f0000-00000000000fffff : alias pam-rom @pc.ram
00000000000f0000-00000000000fffff
  00000000000a0000-00000000000bffff : alias smram-region @pci
00000000000a0000-00000000000bffff
  4000000000000000-7fffffffffffffff : alias pci-hole64 @pci
4000000000000000-7fffffffffffffff
  0000000008000000-00000000ffffffff : alias pci-hole @pci
0000000008000000-00000000ffffffff
  0000000000000000-0000000007ffffff : alias ram-below-4g @pc.ram
0000000000000000-0000000007ffffff
  00000000fee00000-00000000feefffff : apic
pci
0000000000000000-7ffffffffffffffe : pci
  00000000feba0000-00000000febbffff : e1000-mmio
  00000000febf0000-00000000febf0fff : cirrus-mmio
  00000000fc000000-00000000fdffffff : cirrus-pci-bar0
    00000000fc000000-00000000fc7fffff : vga.vram
    00000000fd000000-00000000fd3fffff : cirrus-bitblt-mmio
    00000000fc000000-00000000fc7fffff : cirrus-linear-io
  00000000000a0000-00000000000bffff : cirrus-lowmem-container
    00000000000a0000-00000000000bffff : cirrus-low-memory
  00000000000c0000-00000000000dffff : pc.rom
  00000000000e0000-00000000000fffff : alias isa-bios @pc.bios
00000000fffe0000-00000000ffffffff
  00000000fffe0000-00000000ffffffff : pc.bios
pc.ram
0000000000000000-0000000007ffffff : pc.ram
pc.bios
00000000fffe0000-00000000ffffffff : pc.bios
I/O
0000000000000000-000000000000ffff : io
  000000000000c000-000000000000c03f : e1000-io
  000000000000c040-000000000000c04f : piix-bmdma-container
    000000000000c04c-000000000000c04f : bmdma
    000000000000c048-000000000000c04b : piix-bmdma
    000000000000c044-000000000000c047 : bmdma
    000000000000c040-000000000000c043 : piix-bmdma
  0000000000000cfc-0000000000000cff : pci-conf-data
  0000000000000cf8-0000000000000cfb : pci-conf-idx

PPC (HEAD)
memory
00000000-fffffffe : system
  800a0000-800affff : alias vga.chain4 @vga.vram 80000000-8000ffff
  80880000-808fffff : macio
    808e0000-808fffff : macio-nvram
    808a0000-808a0fff : pmac-ide
    80896000-80895fff : (null)
    80893000-8089303f : alias escc-bar @escc 80013000-8001303f
    80888000-80888fff : dbdma
    80880000-80880fff : heathrow-pic
  80800000-8080ffff : vga.rom
  80000000-807fffff : vga.vram
  800a0000-800bffff : vga-lowmem
  80013000-8001303f : escc
  fee00000-fee00fff : pci-data-idx
  fec00000-fec00fff : pci-conf-idx
  fe000000-fe1fffff : isa-mmio
escc
80013000-8001303f : escc
vga.vram
80000000-807fffff : vga.vram

PPC with my pci-hole patch:
memory
00000000-fffffffe : system
  80013000-8001303f : escc
  fee00000-fee00fff : pci-data-idx
  fec00000-fec00fff : pci-conf-idx
  80000000-fdffffff : alias pci-hole @pci-mmio 80000000-fdffffff
  fe000000-fe1fffff : isa-mmio
pci-mmio
00000000-ffffffff : pci-mmio
  000a0000-000affff : alias vga.chain4 @vga.vram 80000000-8000ffff
  80880000-808fffff : macio
    808e0000-808fffff : macio-nvram
    808a0000-808a0fff : pmac-ide
    80896000-80895fff : (null)
    80893000-8089303f : alias escc-bar @escc 80013000-8001303f
    80888000-80888fff : dbdma
    80880000-80880fff : heathrow-pic
  80800000-8080ffff : vga.rom
  80000000-807fffff : vga.vram
  000a0000-000bffff : vga-lowmem
escc
80013000-8001303f : escc
vga.vram
80000000-807fffff : vga.vram

Sparc64:
0000000000000000-7ffffffffffffffe : system
  000001ff00000000-000001ffffffffff : pci-mmio
    000001ff000a0000-000001ff000affff : alias vga.chain4 @vga.vram
0000000000800000-000000000080ffff
    000001ff03000000-000001ff037fffff : isa-mmio
    000001ff02000000-000001ff02ffffff : isa-mmio
    000001ff01000000-000001ff0100ffff : vga.rom
    000001ff00800000-000001ff00ffffff : vga.vram
    000001ff00000000-000001ff000fffff : alias pci_bridge_mem
@pci_pridge_pci 0000000000000000-00000000000fffff
    000001ff00000000-000001ff000fffff : alias pci_bridge_pref_mem
@pci_pridge_pci 0000000000000000-00000000000fffff
    000001ff00000000-000001ff000fffff : alias pci_bridge_mem
@pci_pridge_pci 0000000000000000-00000000000fffff
    000001ff00000000-000001ff000fffff : alias pci_bridge_pref_mem
@pci_pridge_pci 0000000000000000-00000000000fffff
    000001ff000a0000-000001ff000bffff : vga-lowmem
  000001fe02000000-000001fe0200ffff : apb-pci-ioport
  000001fe01000000-000001fe01ffffff : apb-pci-config
  000001fe00000000-000001fe0000ffff : apb-config
pci_pridge_pci
    ^
0000000000000000-7ffffffffffffffe : pci_pridge_pci
pci_pridge_pci
0000000000000000-7ffffffffffffffe : pci_pridge_pci
vga.vram
0000000000800000-0000000000ffffff : vga.vram

---
 memory.c  |  101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 memory.h  |    2 +
 monitor.c |    7 ++++
 3 files changed, 110 insertions(+), 0 deletions(-)

diff --git a/memory.c b/memory.c
index ba74435..6b33fc4 100644
--- a/memory.c
+++ b/memory.c
@@ -17,6 +17,7 @@
 #include "bitops.h"
 #include "kvm.h"
 #include <assert.h>
+#include "monitor.h"

 unsigned memory_region_transaction_depth = 0;

@@ -1256,3 +1257,103 @@ void set_system_io_map(MemoryRegion *mr)
     address_space_io.root = mr;
     memory_region_update_topology();
 }
+
+typedef struct MemoryRegionList MemoryRegionList;
+typedef struct MemoryRegionListHead MemoryRegionListHead;
+
+struct MemoryRegionList {
+    const MemoryRegion *mr;
+    QLIST_ENTRY(MemoryRegionList) queue;
+};
+
+struct MemoryRegionListHead {
+    QLIST_HEAD(queue, MemoryRegionList) head;
+};
+
+static void mtree_print_mr(Monitor *mon, const MemoryRegion *mr,
+                           unsigned int level, target_phys_addr_t base,
+                           MemoryRegionListHead *print_queue)
+{
+    const MemoryRegion *submr;
+    unsigned int i;
+
+    for (i = 0; i < level; i++) {
+        monitor_printf(mon, "  ");
+    }
+
+    if (mr->alias) {
+        if (print_queue) {
+            MemoryRegionList *ml;
+            bool found = false;
+
+            /* check if the alias is already in the queue */
+            QLIST_FOREACH(ml, &print_queue->head, queue) {
+                if (ml->mr == mr->alias) {
+                    found = true;
+                }
+            }
+
+            if (!found) {
+                ml = g_malloc(sizeof(*ml));
+                ml->mr = mr->alias;
+                QLIST_INSERT_HEAD(&print_queue->head, ml, queue);
+            }
+        }
+        monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " :
alias %s @%s "
+                       TARGET_FMT_plx "-" TARGET_FMT_plx "\n",
+                       base + mr->addr,
+                       base + mr->addr + (target_phys_addr_t)mr->size - 1,
+                       mr->name,
+                       mr->alias->name,
+                       mr->alias_offset + mr->alias->addr,
+                       mr->alias_offset  + mr->alias->addr +
+                       (target_phys_addr_t)mr->size - 1);
+
+    } else {
+        monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " : %s\n",
+                       base + mr->addr,
+                       base + mr->addr + (target_phys_addr_t)mr->size - 1,
+                       mr->name);
+    }
+    QTAILQ_FOREACH(submr, &mr->subregions, subregions_link) {
+        mtree_print_mr(mon, submr, level + 1, base + mr->addr, print_queue);
+    }
+}
+
+void mtree_info(Monitor *mon)
+{
+    MemoryRegionListHead *ml_head, *ml_head2, *ml_tmp;
+    MemoryRegionList *ml, *ml2;
+
+    ml_head = g_malloc(sizeof(*ml));
+    QLIST_INIT(&ml_head->head);
+
+    monitor_printf(mon, "memory\n");
+    mtree_print_mr(mon, address_space_memory.root, 0, 0, ml_head);
+
+    ml_head2 = g_malloc(sizeof(*ml));
+
+    /* print aliased regions */
+    for (;;) {
+        QLIST_INIT(&ml_head2->head);
+
+        QLIST_FOREACH_SAFE(ml, &ml_head->head, queue, ml2) {
+            monitor_printf(mon, "%s\n", ml->mr->name);
+            mtree_print_mr(mon, ml->mr, 0, 0, ml_head2);
+            g_free(ml);
+        }
+        if (QLIST_EMPTY(&ml_head->head)) {
+            break;
+        }
+        ml_tmp = ml_head;
+        ml_head = ml_head2;
+        ml_head2 = ml_tmp;
+    }
+
+#ifdef TARGET_I386
+    monitor_printf(mon, "I/O\n");
+    mtree_print_mr(mon, address_space_io.root, 0, 0, ml_head);
+#endif
+    g_free(ml_head2);
+    g_free(ml_head);
+}
diff --git a/memory.h b/memory.h
index 06b83ae..09d8e29 100644
--- a/memory.h
+++ b/memory.h
@@ -500,6 +500,8 @@ void memory_region_transaction_begin(void);
  */
 void memory_region_transaction_commit(void);

+void mtree_info(Monitor *mon);
+
 #endif

 #endif
diff --git a/monitor.c b/monitor.c
index 8ec2c5e..f86fff6 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2978,6 +2978,13 @@ static const mon_cmd_t info_cmds[] = {
     },
 #endif
     {
+        .name       = "mtree",
+        .args_type  = "",
+        .params     = "",
+        .help       = "show memory tree",
+        .mhandler.info = mtree_info,
+    },
+    {
         .name       = "jit",
         .args_type  = "",
         .params     = "",
-- 
1.6.2.4

[-- Attachment #2: 0001-memory-simple-memory-tree-printer.patch --]
[-- Type: text/x-diff, Size: 4838 bytes --]

From c68970d45db864ad80f1387cbd1e3792e8f15c54 Mon Sep 17 00:00:00 2001
Message-Id: <c68970d45db864ad80f1387cbd1e3792e8f15c54.1316981935.git.blauwirbel@gmail.com>
From: Blue Swirl <blauwirbel@gmail.com>
Date: Sun, 11 Sep 2011 20:22:05 +0000
Subject: [PATCH] memory: simple memory tree printer

Add a monitor command 'info mtree' to show the memory hierarchy
much like /proc/iomem in Linux.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 memory.c  |  101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 memory.h  |    2 +
 monitor.c |    7 ++++
 3 files changed, 110 insertions(+), 0 deletions(-)

diff --git a/memory.c b/memory.c
index ba74435..6b33fc4 100644
--- a/memory.c
+++ b/memory.c
@@ -17,6 +17,7 @@
 #include "bitops.h"
 #include "kvm.h"
 #include <assert.h>
+#include "monitor.h"
 
 unsigned memory_region_transaction_depth = 0;
 
@@ -1256,3 +1257,103 @@ void set_system_io_map(MemoryRegion *mr)
     address_space_io.root = mr;
     memory_region_update_topology();
 }
+
+typedef struct MemoryRegionList MemoryRegionList;
+typedef struct MemoryRegionListHead MemoryRegionListHead;
+
+struct MemoryRegionList {
+    const MemoryRegion *mr;
+    QLIST_ENTRY(MemoryRegionList) queue;
+};
+
+struct MemoryRegionListHead {
+    QLIST_HEAD(queue, MemoryRegionList) head;
+};
+
+static void mtree_print_mr(Monitor *mon, const MemoryRegion *mr,
+                           unsigned int level, target_phys_addr_t base,
+                           MemoryRegionListHead *print_queue)
+{
+    const MemoryRegion *submr;
+    unsigned int i;
+
+    for (i = 0; i < level; i++) {
+        monitor_printf(mon, "  ");
+    }
+
+    if (mr->alias) {
+        if (print_queue) {
+            MemoryRegionList *ml;
+            bool found = false;
+
+            /* check if the alias is already in the queue */
+            QLIST_FOREACH(ml, &print_queue->head, queue) {
+                if (ml->mr == mr->alias) {
+                    found = true;
+                }
+            }
+
+            if (!found) {
+                ml = g_malloc(sizeof(*ml));
+                ml->mr = mr->alias;
+                QLIST_INSERT_HEAD(&print_queue->head, ml, queue);
+            }
+        }
+        monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " : alias %s @%s "
+                       TARGET_FMT_plx "-" TARGET_FMT_plx "\n",
+                       base + mr->addr,
+                       base + mr->addr + (target_phys_addr_t)mr->size - 1,
+                       mr->name,
+                       mr->alias->name,
+                       mr->alias_offset + mr->alias->addr,
+                       mr->alias_offset  + mr->alias->addr +
+                       (target_phys_addr_t)mr->size - 1);
+
+    } else {
+        monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " : %s\n",
+                       base + mr->addr,
+                       base + mr->addr + (target_phys_addr_t)mr->size - 1,
+                       mr->name);
+    }
+    QTAILQ_FOREACH(submr, &mr->subregions, subregions_link) {
+        mtree_print_mr(mon, submr, level + 1, base + mr->addr, print_queue);
+    }
+}
+
+void mtree_info(Monitor *mon)
+{
+    MemoryRegionListHead *ml_head, *ml_head2, *ml_tmp;
+    MemoryRegionList *ml, *ml2;
+
+    ml_head = g_malloc(sizeof(*ml));
+    QLIST_INIT(&ml_head->head);
+
+    monitor_printf(mon, "memory\n");
+    mtree_print_mr(mon, address_space_memory.root, 0, 0, ml_head);
+
+    ml_head2 = g_malloc(sizeof(*ml));
+
+    /* print aliased regions */
+    for (;;) {
+        QLIST_INIT(&ml_head2->head);
+
+        QLIST_FOREACH_SAFE(ml, &ml_head->head, queue, ml2) {
+            monitor_printf(mon, "%s\n", ml->mr->name);
+            mtree_print_mr(mon, ml->mr, 0, 0, ml_head2);
+            g_free(ml);
+        }
+        if (QLIST_EMPTY(&ml_head->head)) {
+            break;
+        }
+        ml_tmp = ml_head;
+        ml_head = ml_head2;
+        ml_head2 = ml_tmp;
+    }
+
+#ifdef TARGET_I386
+    monitor_printf(mon, "I/O\n");
+    mtree_print_mr(mon, address_space_io.root, 0, 0, ml_head);
+#endif
+    g_free(ml_head2);
+    g_free(ml_head);
+}
diff --git a/memory.h b/memory.h
index 06b83ae..09d8e29 100644
--- a/memory.h
+++ b/memory.h
@@ -500,6 +500,8 @@ void memory_region_transaction_begin(void);
  */
 void memory_region_transaction_commit(void);
 
+void mtree_info(Monitor *mon);
+
 #endif
 
 #endif
diff --git a/monitor.c b/monitor.c
index 8ec2c5e..f86fff6 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2978,6 +2978,13 @@ static const mon_cmd_t info_cmds[] = {
     },
 #endif
     {
+        .name       = "mtree",
+        .args_type  = "",
+        .params     = "",
+        .help       = "show memory tree",
+        .mhandler.info = mtree_info,
+    },
+    {
         .name       = "jit",
         .args_type  = "",
         .params     = "",
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2011-09-26 17:13 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-17 19:27 [Qemu-devel] [PATCH v2] memory: simple memory tree printer Blue Swirl
2011-09-18 12:57 ` Jan Kiszka
2011-09-18 13:53 ` Avi Kivity
2011-09-18 14:07   ` Blue Swirl
2011-09-18 14:26     ` Avi Kivity
2011-09-25 20:19 Blue Swirl
2011-09-26  8:07 ` Wayne Xia
2011-09-26  9:45 ` Avi Kivity
2011-09-26 17:13   ` Blue Swirl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).