[Crash-utility] [PATCH] kmem: update n option to dump memory block
Masayoshi Mizuma
msys.mizuma at gmail.com
Tue Oct 2 21:38:25 UTC 2018
Hi Dave,
Thank you for your comment.
On Tue, Oct 02, 2018 at 12:02:35PM -0400, Dave Anderson wrote:
>
>
> ----- Original Message -----
> > From: Masayoshi Mizuma <m.mizuma at jp.fujitsu.com>
> >
> > Update for the "kmem -n" option to also dump memory block.
> > Currently, "kmem -n" shows the memory section only. This
> > patch gets available the memory block as well if 'memory_block'
> > structure and 'memory_subsys' symbol exist.
> > The memory block information is useful to investigate memory
> > hot-plug issue.
>
>
> Hello Masa,
>
> First let me say that I appreciate the work you've done to add this new information.
>
> However, I don't like the new output format...
>
> Taking a simple example, the current display looks like this:
>
> NR SECTION CODED_MEM_MAP MEM_MAP PFN
> 0 ffff880002664000 ffffea0000000000 ffffea0000000000 0
> 1 ffff880002664020 ffffea0000000000 ffffea0000340000 32768
> 2 ffff880002664040 ffffea0000000000 ffffea0000680000 65536
> 3 ffff880002664060 ffffea0000000000 ffffea00009c0000 98304
> 4 ffff880002664080 ffffea0000000000 ffffea0000d00000 131072
> 5 ffff8800026640a0 ffffea0000000000 ffffea0001040000 163840
> 6 ffff8800026640c0 ffffea0000000000 ffffea0001380000 196608
> 7 ffff8800026640e0 ffffea0000000000 ffffea00016c0000 229376
>
> With your patch on a system without memory blocks, it looks like this:
>
> NR SECTION CODED_MEM_MAP MEM_MAP PFN STATE
> 0 ffff880002664000 ffffea0000000000 ffffea0000000000 0 PRESENT|HAS_MEMMAP
> 1 ffff880002664020 ffffea0000000000 ffffea0000340000 32768 PRESENT|HAS_MEMMAP
> 2 ffff880002664040 ffffea0000000000 ffffea0000680000 65536 PRESENT|HAS_MEMMAP
> 3 ffff880002664060 ffffea0000000000 ffffea00009c0000 98304 PRESENT|HAS_MEMMAP
> 4 ffff880002664080 ffffea0000000000 ffffea0000d00000 131072 PRESENT|HAS_MEMMAP
> 5 ffff8800026640a0 ffffea0000000000 ffffea0001040000 163840 PRESENT|HAS_MEMMAP
> 6 ffff8800026640c0 ffffea0000000000 ffffea0001380000 196608 PRESENT|HAS_MEMMAP
> 7 ffff8800026640e0 ffffea0000000000 ffffea00016c0000 229376 PRESENT|HAS_MEMMAP
>
> Your patch stretches the output well beyond the preferred 80 column maximum,
> which I try to avoid if at all possible.
>
> Could you please:
>
> (1) restore the original display size w/respect to the "NR" column
> (2) restore the left-justified "PFN" header string.
> (3) put the new "STATE" column as a fixed-size column somewhere
> before the "PFN" column, and instead of using the PRESENT,
> HAS_MEMMAP, and ONLINE strings, use "P", "M" and "O".
I think (3) is nice idea!
>
> That will keep it under 80 columns, and the "P", "M" and "O" should
> be described in the "kmem" help page for the -n option (which
> currently doesn't even have the memory section in the example).
>
> Now, when memory blocks are supported, the output is really difficult
> to read, mainly because each of the (possible hundreds of) entries
> has two headers.
>
> I understand that you want to link the memory sections with the memory
> blocks, but here's what I suggest the output should be. To clarify their
> relationship, you could add a "NR" column to your memory block display,
> and separate the two sections, to look like this:
>
> crash> kmem -n
> ... [ cut ] ...
>
> NR SECTION CODED_MEM_MAP MEM_MAP STATE PFN
> 0 ffff88047e5d6000 ffffea0000000000 ffffea0000000000 PM 0
> 1 ffff88047e5d6020 ffffea0000000000 ffffea0000200000 PM 32768
> 2 ffff88047e5d6040 ffffea0000000000 ffffea0000400000 PM 65536
> 3 ffff88047e5d6060 ffffea0000000000 ffffea0000600000 PM 98304
> ...
>
> NR MEM_BLOCK NAME PHYSICAL RANGE STATE
> 0 ffff880181e59000 memory0 0 - 7ffffff ONLINE
> 1 ffff880181e58c00 memory1 8000000 - fffffff ONLINE
> 2 ffff88047e268000 memory2 10000000 - 17ffffff ONLINE
> 3 ffff88047e268400 memory3 18000000 - 1fffffff ONLINE
> ...
How about the following layout? The following shows the sections
which belong to the memory block.
crash> kmem -n
...
NR SECTION CODED_MEM_MAP MEM_MAP STATE PFN
0 ffff88047e5d6000 ffffea0000000000 ffffea0000000000 PM 0
1 ffff88047e5d6020 ffffea0000000000 ffffea0000200000 PM 32768
2 ffff88047e5d6040 ffffea0000000000 ffffea0000400000 PM 65536
3 ffff88047e5d6060 ffffea0000000000 ffffea0000600000 PM 98304
...
MEM_BLOCK NAME PHYSICAL RANGE STATE SECTIONS
ffff880181e59000 memory0 0 - 7ffffff ONLINE 0-3
ffff880181e58c00 memory1 8000000 - fffffff ONLINE 4-7
ffff88047e268000 memory2 10000000 - 17ffffff ONLINE 8-11
ffff88047e268400 memory3 18000000 - 1fffffff ONLINE 12-15
...
>
> Also, I would prefer that you separate the functionality for the
> sake of clarity and maintainability, for example:
>
> @@ -16355,7 +16357,7 @@ dump_memory_nodes(int initialize)
> }
>
> if (IS_SPARSEMEM())
> - dump_mem_sections(initialize);
> + dump_mem_block_and_sections(initialize);
> }
>
> Could you create a separate dump_memory_blocks() function? I understand
> that other functions can and should be utilized by both functions.
Got it.
>
> Lastly, for any new additions to the offset_table, please add them
> to the dump_offset_table() function in symbols.c for "help -o".
> I mistakenly forgot to mention that when accepting your "dev -p" patch,
> but I subsequently added them.
Thanks, got it.
- Masa
>
> Thanks,
> Dave
>
>
>
>
>
>
>
> >
> > Signed-off-by: Masayoshi Mizuma <m.mizuma at jp.fujitsu.com>
> > ---
> > defs.h | 8 ++
> > memory.c | 412 +++++++++++++++++++++++++++++++++++++++++++++++++------
> > 2 files changed, 379 insertions(+), 41 deletions(-)
> >
> > diff --git a/defs.h b/defs.h
> > index 5b64bb7..f707c64 100644
> > --- a/defs.h
> > +++ b/defs.h
> > @@ -2049,6 +2049,14 @@ struct offset_table { /* stash of
> > commonly-used offsets */
> > long pci_bus_self;
> > long device_kobj;
> > long kobject_name;
> > + long memory_block_dev;
> > + long memory_block_start_section_nr;
> > + long mem_section_pageblock_flags;
> > + long memory_block_state;
> > + long memory_block_nid;
> > + long bus_type_p;
> > + long device_private_device;
> > + long device_private_knode_bus;
> > };
> >
> > struct size_table { /* stash of commonly-used sizes */
> > diff --git a/memory.c b/memory.c
> > index ea25047..c7a4787 100644
> > --- a/memory.c
> > +++ b/memory.c
> > @@ -254,14 +254,16 @@ static void PG_reserved_flag_init(void);
> > static void PG_slab_flag_init(void);
> > static ulong nr_blockdev_pages(void);
> > void sparse_mem_init(void);
> > -void dump_mem_sections(int);
> > +void dump_mem_block_and_sections(int);
> > +void _dump_mem_block_and_sections(void);
> > +void dump_mem_sections(void);
> > void list_mem_sections(void);
> > ulong sparse_decode_mem_map(ulong, ulong);
> > char *read_mem_section(ulong);
> > ulong nr_to_section(ulong);
> > int valid_section(ulong);
> > int section_has_mem_map(ulong);
> > -ulong section_mem_map_addr(ulong);
> > +ulong section_mem_map_addr(ulong, int);
> > ulong valid_section_nr(ulong);
> > ulong pfn_to_map(ulong);
> > static int get_nodes_online(void);
> > @@ -5528,7 +5530,7 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi)
> > pc->curcmd_flags |= HEADER_PRINTED;
> > }
> >
> > - pp = section_mem_map_addr(section);
> > + pp = section_mem_map_addr(section, 0);
> > pp = sparse_decode_mem_map(pp, section_nr);
> > phys = (physaddr_t) section_nr * PAGES_PER_SECTION() * PAGESIZE();
> > section_size = PAGES_PER_SECTION();
> > @@ -13389,7 +13391,7 @@ is_page_ptr(ulong addr, physaddr_t *phys)
> > nr_mem_sections = vt->max_mem_section_nr+1;
> > for (nr = 0; nr < nr_mem_sections ; nr++) {
> > if ((sec_addr = valid_section_nr(nr))) {
> > - coded_mem_map = section_mem_map_addr(sec_addr);
> > + coded_mem_map = section_mem_map_addr(sec_addr, 0);
> > mem_map = sparse_decode_mem_map(coded_mem_map, nr);
> > end_mem_map = mem_map + (PAGES_PER_SECTION() * SIZE(page));
> >
> > @@ -16355,7 +16357,7 @@ dump_memory_nodes(int initialize)
> > }
> >
> > if (IS_SPARSEMEM())
> > - dump_mem_sections(initialize);
> > + dump_mem_block_and_sections(initialize);
> > }
> >
> > /*
> > @@ -17140,7 +17142,7 @@ section_has_mem_map(ulong addr)
> > }
> >
> > ulong
> > -section_mem_map_addr(ulong addr)
> > +section_mem_map_addr(ulong addr, int raw)
> > {
> > char *mem_section;
> > ulong map;
> > @@ -17148,7 +17150,8 @@ section_mem_map_addr(ulong addr)
> > if ((mem_section = read_mem_section(addr))) {
> > map = ULONG(mem_section +
> > OFFSET(mem_section_section_mem_map));
> > - map &= SECTION_MAP_MASK;
> > + if (!raw)
> > + map &= SECTION_MAP_MASK;
> > return map;
> > }
> > return 0;
> > @@ -17179,7 +17182,7 @@ pfn_to_map(ulong pfn)
> >
> > if (section_has_mem_map(section)) {
> > page_offset = pfn - section_nr_to_pfn(section_nr);
> > - coded_mem_map = section_mem_map_addr(section);
> > + coded_mem_map = section_mem_map_addr(section, 0);
> > mem_map = sparse_decode_mem_map(coded_mem_map, section_nr) +
> > (page_offset * SIZE(page));
> > return mem_map;
> > @@ -17188,16 +17191,365 @@ pfn_to_map(ulong pfn)
> > return 0;
> > }
> >
> > -void
> > -dump_mem_sections(int initialize)
> > +struct memory_block_info {
> > + ulong memory_block;
> > + ulong start_sec;
> > + ulong start_pfn;
> > + ulong nid;
> > + char state[24];
> > + char name[32];
> > +};
> > +
> > +#define MIN_MEMORY_BLOCK_SIZE (1UL << _SECTION_SIZE_BITS)
> > +
> > +#define MEM_ONLINE (1<<0)
> > +#define MEM_GOING_OFFLINE (1<<1)
> > +#define MEM_OFFLINE (1<<2)
> > +#define MEM_GOING_ONLINE (1<<3)
> > +#define MEM_CANCEL_ONLINE (1<<4)
> > +#define MEM_CANCEL_OFFLINE (1<<5)
> > +
> > +static void
> > +fill_memory_block_state(ulong memblock, char *buf)
> > {
> > - ulong nr, max, addr;
> > - ulong nr_mem_sections;
> > + ulong state;
> > +
> > + memset(buf, 0, sizeof(*buf) * BUFSIZE);
> > +
> > + readmem(memblock + OFFSET(memory_block_state), KVADDR, &state,
> > + sizeof(void *), "memory_block state", FAULT_ON_ERROR);
> > +
> > + switch (state) {
> > + case MEM_ONLINE:
> > + sprintf(buf, "%s", "ONLINE");
> > + break;
> > + case MEM_GOING_OFFLINE:
> > + sprintf(buf, "%s", "GOING_OFFLINE");
> > + break;
> > + case MEM_OFFLINE:
> > + sprintf(buf, "%s", "OFFLINE");
> > + break;
> > + case MEM_GOING_ONLINE:
> > + sprintf(buf, "%s", "GOING_ONLINE");
> > + break;
> > + case MEM_CANCEL_ONLINE:
> > + sprintf(buf, "%s", "CANCEL_ONLINE");
> > + break;
> > + case MEM_CANCEL_OFFLINE:
> > + sprintf(buf, "%s", "CANCEL_OFFLINE");
> > + break;
> > + default:
> > + sprintf(buf, "%s", "UNKNOWN");
> > + }
> > +}
> > +
> > +static void
> > +fill_mem_section_state(ulong state, char *buf)
> > +{
> > + int bufidx = 0, others = 0;
> > +
> > + memset(buf, 0, sizeof(*buf) * BUFSIZE);
> > +
> > +#define printflag(X) sprintf(buf + bufidx, X, others++ ? "|" : "")
> > +
> > + if (state & SECTION_MARKED_PRESENT)
> > + bufidx += printflag("%sPRESENT");
> > + if (state & SECTION_HAS_MEM_MAP)
> > + bufidx += printflag("%sHAS_MEMMAP");
> > + if (state & SECTION_IS_ONLINE)
> > + bufidx += printflag("%sONLINE");
> > +}
> > +
> > +static ulong
> > +pfn_to_phys(ulong pfn)
> > +{
> > + return pfn << PAGE_SHIFT;
> > +}
> > +
> > +static ulong
> > +get_memory_block_size(void)
> > +{
> > + static ulong blksz;
> > +
> > + if (blksz)
> > + return blksz;
> > +
> > + if (symbol_exists("memory_block_size_probed"))
> > + get_symbol_data("memory_block_size_probed", sizeof(ulong),
> > + &blksz);
> > + else
> > + blksz = MIN_MEMORY_BLOCK_SIZE;
> > +
> > + return blksz;
> > +}
> > +
> > +static void
> > +fill_memory_block_name(ulong memblock, char *name)
> > +{
> > + ulong kobj, value;
> > +
> > + memset(name, 0, sizeof(*name) * BUFSIZE);
> > +
> > + kobj = memblock + OFFSET(memory_block_dev) + OFFSET(device_kobj);
> > +
> > + readmem(kobj + OFFSET(kobject_name),
> > + KVADDR, &value, sizeof(void *), "kobject name",
> > + FAULT_ON_ERROR);
> > +
> > + read_string(value, name, BUFSIZE-1);
> > +}
> > +
> > +static void
> > +fill_memory_block_info(ulong mb, struct memory_block_info *mbi)
> > +{
> > + ulong start, start_pfn, nid;
> > + char statebuf[BUFSIZE];
> > + char name[BUFSIZE];
> > +
> > + readmem(mb + OFFSET(memory_block_start_section_nr), KVADDR,
> > + &start, sizeof(void *), "memory_block start_section_nr",
> > + FAULT_ON_ERROR);
> > +
> > + start_pfn = section_nr_to_pfn(start);
> > + fill_memory_block_state(mb, statebuf);
> > + fill_memory_block_name(mb, name);
> > +
> > + mbi->memory_block = mb;
> > + mbi->start_sec = start;
> > + mbi->start_pfn = start_pfn;
> > + strncpy(mbi->state, statebuf, sizeof(mbi->state));
> > + strncpy(mbi->name, name, sizeof(mbi->name));
> > + if (MEMBER_EXISTS("memory_block", "nid")) {
> > + readmem(mb + OFFSET(memory_block_nid), KVADDR, &nid,
> > + sizeof(void *), "memory_block nid", FAULT_ON_ERROR);
> > + mbi->nid = nid;
> > + }
> > +}
> > +
> > +static void
> > +init_memory_block(void)
> > +{
> > + MEMBER_OFFSET_INIT(bus_type_p, "bus_type", "p");
> > + MEMBER_OFFSET_INIT(subsys_private_klist_devices,
> > + "subsys_private", "klist_devices");
> > + MEMBER_OFFSET_INIT(klist_k_list, "klist", "k_list");
> > + MEMBER_OFFSET_INIT(klist_node_n_node, "klist_node", "n_node");
> > + MEMBER_OFFSET_INIT(device_private_knode_bus,
> > + "device_private", "knode_bus");
> > + MEMBER_OFFSET_INIT(device_private_device, "device_private", "device");
> > + MEMBER_OFFSET_INIT(memory_block_dev, "memory_block", "dev");
> > + MEMBER_OFFSET_INIT(memory_block_start_section_nr,
> > + "memory_block", "start_section_nr");
> > + MEMBER_OFFSET_INIT(memory_block_state, "memory_block", "state");
> > + if (MEMBER_EXISTS("memory_block", "nid"))
> > + MEMBER_OFFSET_INIT(memory_block_nid, "memory_block", "nid");
> > +}
> > +
> > +static struct memory_block_info*
> > +parse_memory_block(void)
> > +{
> > + ulong memory_subsys = symbol_value("memory_subsys");
> > + ulong private, klist, memory_block, device;
> > + ulong *klistbuf;
> > + int klistcnt, i;
> > + struct list_data list_data, *ld;
> > + struct memory_block_info *memory_block_info;
> > +
> > + init_memory_block();
> > +
> > + readmem(memory_subsys + OFFSET(bus_type_p), KVADDR, &private,
> > + sizeof(void *), "memory_subsys.private", FAULT_ON_ERROR);
> > + klist = private + OFFSET(subsys_private_klist_devices) +
> > + OFFSET(klist_k_list);
> > + ld = &list_data;
> > + BZERO(ld, sizeof(struct list_data));
> > +
> > + ld->start = klist;
> > + ld->end = klist;
> > + ld->list_head_offset = OFFSET(klist_node_n_node) +
> > + OFFSET(device_private_knode_bus);
> > + hq_open();
> > + klistcnt = do_list(ld);
> > + klistbuf = (ulong *)GETBUF(klistcnt * sizeof(ulong));
> > + klistcnt = retrieve_list(klistbuf, klistcnt);
> > + hq_close();
> > +
> > + memory_block_info = calloc(klistcnt + 1,
> > + sizeof(struct memory_block_info));
> > + if (!memory_block_info)
> > + error(FATAL, "cannot allocate memory for memory_block_info\n");
> > +
> > + for (i = 0; i < klistcnt; i++) {
> > + readmem(klistbuf[i] + OFFSET(device_private_device), KVADDR,
> > + &device, sizeof(void *), "device_private device",
> > + FAULT_ON_ERROR);
> > + memory_block = device - OFFSET(memory_block_dev);
> > + fill_memory_block_info(memory_block, &memory_block_info[i]);
> > + }
> > + FREEBUF(klistbuf);
> > +
> > + return memory_block_info;
> > +}
> > +
> > +static struct memory_block_info*
> > +get_memory_block_info(ulong pfn, struct memory_block_info *mbi_tbl)
> > +{
> > + int i;
> > +
> > + for (i = 0; mbi_tbl[i].memory_block != 0; i++)
> > + if (pfn == mbi_tbl[i].start_pfn)
> > + return &mbi_tbl[i];
> > +
> > + return NULL;
> > +}
> > +
> > +
> > +static int
> > +is_memory_block_head(ulong pfn)
> > +{
> > + ulong nr_pages = get_memory_block_size() / PAGE_SIZE;
> > +
> > + return (pfn % nr_pages) == 0;
> > +}
> > +
> > +static void
> > +print_memory_block(ulong pfn, ulong nr_mb_pages, struct memory_block_info
> > *mbi)
> > +{
> > + char buf1[BUFSIZE];
> > + char buf2[BUFSIZE];
> > + char buf3[BUFSIZE];
> > + char buf4[BUFSIZE];
> > + char buf5[BUFSIZE];
> > + char buf6[BUFSIZE];
> > +
> > + if (MEMBER_EXISTS("memory_block", "nid"))
> > + fprintf(fp, " %s %s %s - %s %s %s\n",
> > + mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
> > + MKSTR(mbi->memory_block)),
> > + mkstring(buf2, 12, CENTER, mbi->name),
> > + mkstring(buf3, PADDR_PRLEN, RJUST|LONG_HEX,
> > + MKSTR(pfn_to_phys(pfn))),
> > + mkstring(buf4, PADDR_PRLEN, LJUST|LONG_HEX,
> > + MKSTR(pfn_to_phys(pfn + nr_mb_pages) - 1)),
> > + mkstring(buf5, strlen("NODE"), CENTER|LONG_DEC,
> > + MKSTR(mbi->nid)),
> > + mkstring(buf6, strlen("CANCEL_OFFLINE"), LJUST,
> > + mbi->state));
> > + else
> > + fprintf(fp, " %s %s %s - %s %s\n",
> > + mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
> > + MKSTR(mbi->memory_block)),
> > + mkstring(buf2, 10, CENTER, mbi->name),
> > + mkstring(buf3, PADDR_PRLEN, RJUST|LONG_HEX,
> > + MKSTR(pfn_to_phys(pfn))),
> > + mkstring(buf4, PADDR_PRLEN, LJUST|LONG_HEX,
> > + MKSTR(pfn_to_phys(pfn + nr_mb_pages) - 1)),
> > + mkstring(buf5, strlen("CANCEL_OFFLINE"), LJUST,
> > + mbi->state));
> > +}
> > +
> > +static void
> > +do_mem_block_and_sections(int print_memblk, struct memory_block_info
> > *mbi_tbl)
> > +{
> > + ulong nr, addr;
> > + ulong nr_mem_sections, nr_mb_pages;
> > ulong coded_mem_map, mem_map, pfn;
> > + struct memory_block_info *mbi;
> > + char mb_hdr[BUFSIZE];
> > + char ms_hdr[BUFSIZE];
> > + char statebuf[BUFSIZE];
> > char buf1[BUFSIZE];
> > char buf2[BUFSIZE];
> > char buf3[BUFSIZE];
> > char buf4[BUFSIZE];
> > + char buf5[BUFSIZE];
> > +
> > + nr_mb_pages = PAGES_PER_SECTION() *
> > + get_memory_block_size() / MIN_MEMORY_BLOCK_SIZE;
> > +
> > + if (MEMBER_EXISTS("memory_block", "nid"))
> > + sprintf(mb_hdr, "\n%s %s %s %s %s\n",
> > + mkstring(buf1, VADDR_PRLEN, CENTER|LJUST, "MEM_BLOCK"),
> > + mkstring(buf2, 10, CENTER, "NAME"),
> > + mkstring(buf3, PADDR_PRLEN*2 + 2, CENTER, "PHYSICAL RANGE"),
> > + mkstring(buf4, strlen("NODE"), CENTER, "NODE"),
> > + mkstring(buf5, strlen("CANCEL_OFFLINE"), LJUST, "STATE"));
> > + else
> > + sprintf(mb_hdr, "\n%s %s %s %s\n",
> > + mkstring(buf1, VADDR_PRLEN, CENTER|LJUST, "MEM_BLOCK"),
> > + mkstring(buf2, 10, CENTER, "NAME"),
> > + mkstring(buf3, PADDR_PRLEN*2, CENTER, "PHYSICAL RANGE"),
> > + mkstring(buf4, strlen("CANCEL_OFFLINE"), LJUST, "STATE"));
> > +
> > + sprintf(ms_hdr, "NR %s %s %s %s %s\n",
> > + mkstring(buf1, VADDR_PRLEN, CENTER|LJUST, "SECTION"),
> > + mkstring(buf2, MAX(VADDR_PRLEN, strlen("CODED_MEM_MAP")),
> > + CENTER|LJUST, "CODED_MEM_MAP"),
> > + mkstring(buf3, VADDR_PRLEN, CENTER|LJUST, "MEM_MAP"),
> > + mkstring(buf4, 12, CENTER, "PFN"),
> > + mkstring(buf5, 12, LJUST, "STATE"));
> > +
> > + if (!print_memblk)
> > + fprintf(fp, "%s", ms_hdr);
> > +
> > + nr_mem_sections = NR_MEM_SECTIONS();
> > + for (nr = 0; nr < nr_mem_sections ; nr++) {
> > + addr = valid_section_nr(nr);
> > + if (addr) {
> > + coded_mem_map = section_mem_map_addr(addr, 0);
> > + mem_map = sparse_decode_mem_map(coded_mem_map, nr);
> > + pfn = section_nr_to_pfn(nr);
> > + fill_mem_section_state(section_mem_map_addr(addr, 1),
> > + statebuf);
> > +
> > + if ((print_memblk) && (is_memory_block_head(pfn))) {
> > + mbi = get_memory_block_info(pfn, mbi_tbl);
> > + fprintf(fp, "%s", mb_hdr);
> > + print_memory_block(pfn, nr_mb_pages, mbi);
> > + fprintf(fp, "%s", ms_hdr);
> > + }
> > +
> > + fprintf(fp, "%5ld %s %s %s %s %s\n",
> > + nr,
> > + mkstring(buf1, VADDR_PRLEN,
> > + CENTER|LONG_HEX, MKSTR(addr)),
> > + mkstring(buf2, MAX(VADDR_PRLEN,
> > + strlen("CODED_MEM_MAP")),
> > + CENTER|LONG_HEX|RJUST, MKSTR(coded_mem_map)),
> > + mkstring(buf3, VADDR_PRLEN,
> > + CENTER|LONG_HEX|RJUST, MKSTR(mem_map)),
> > + pc->output_radix == 10 ?
> > + mkstring(buf4, 12,
> > + LONG_DEC|LJUST, MKSTR(pfn)) :
> > + mkstring(buf4, 12,
> > + LONG_HEX|LJUST, MKSTR(pfn)),
> > + mkstring(buf5, 12, LJUST, statebuf));
> > + }
> > + }
> > +}
> > +
> > +
> > +void
> > +dump_mem_sections(void)
> > +{
> > + do_mem_block_and_sections(0, NULL);
> > +}
> > +
> > +void
> > +_dump_mem_block_and_sections(void)
> > +{
> > + struct memory_block_info *mbi_tbl;
> > +
> > + mbi_tbl = parse_memory_block();
> > + do_mem_block_and_sections(1, mbi_tbl);
> > + free(mbi_tbl);
> > +}
> > +
> > +void
> > +dump_mem_block_and_sections(int initialize)
> > +{
> > + ulong nr, max;
> > + ulong nr_mem_sections;
> >
> > nr_mem_sections = NR_MEM_SECTIONS();
> >
> > @@ -17212,34 +17564,12 @@ dump_mem_sections(int initialize)
> >
> > fprintf(fp, "\n");
> > pad_line(fp, BITS32() ? 59 : 67, '-');
> > - fprintf(fp, "\n\nNR %s %s %s PFN\n",
> > - mkstring(buf1, VADDR_PRLEN, CENTER|LJUST, "SECTION"),
> > - mkstring(buf2, MAX(VADDR_PRLEN,strlen("CODED_MEM_MAP")),
> > - CENTER|LJUST, "CODED_MEM_MAP"),
> > - mkstring(buf3, VADDR_PRLEN, CENTER|LJUST, "MEM_MAP"));
> > -
> > - for (nr = 0; nr < nr_mem_sections ; nr++) {
> > - if ((addr = valid_section_nr(nr))) {
> > - coded_mem_map = section_mem_map_addr(addr);
> > - mem_map = sparse_decode_mem_map(coded_mem_map,nr);
> > - pfn = section_nr_to_pfn(nr);
> > -
> > - fprintf(fp, "%2ld %s %s %s %s\n",
> > - nr,
> > - mkstring(buf1, VADDR_PRLEN,
> > - CENTER|LONG_HEX, MKSTR(addr)),
> > - mkstring(buf2, MAX(VADDR_PRLEN,
> > - strlen("CODED_MEM_MAP")),
> > - CENTER|LONG_HEX|RJUST, MKSTR(coded_mem_map)),
> > - mkstring(buf3, VADDR_PRLEN,
> > - CENTER|LONG_HEX|RJUST, MKSTR(mem_map)),
> > - pc->output_radix == 10 ?
> > - mkstring(buf4, VADDR_PRLEN,
> > - LONG_DEC|LJUST, MKSTR(pfn)) :
> > - mkstring(buf4, VADDR_PRLEN,
> > - LONG_HEX|LJUST, MKSTR(pfn)));
> > - }
> > - }
> > + fprintf(fp, "\n\n");
> > + if ((!STRUCT_EXISTS("memory_block")) ||
> > + (!symbol_exists("memory_subsys")))
> > + dump_mem_sections();
> > + else
> > + _dump_mem_block_and_sections();
> > }
> >
> > void
> > @@ -17251,7 +17581,7 @@ list_mem_sections(void)
> >
> > for (nr = 0; nr <= nr_mem_sections ; nr++) {
> > if ((addr = valid_section_nr(nr))) {
> > - coded_mem_map = section_mem_map_addr(addr);
> > + coded_mem_map = section_mem_map_addr(addr, 0);
> > fprintf(fp,
> > "nr=%ld section = %lx coded_mem_map=%lx pfn=%ld mem_map=%lx\n",
> > nr,
> > --
> > 2.19.0
> >
> > --
> > Crash-utility mailing list
> > Crash-utility at redhat.com
> > https://www.redhat.com/mailman/listinfo/crash-utility
> >
>
> --
> Crash-utility mailing list
> Crash-utility at redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility
More information about the Crash-utility
mailing list