From: Masayoshi Mizuma <m.mizuma(a)jp.fujitsu.com>
Fix for Linux 5.4-rc1 and later kernels that contain commit
b6c88d3b9d38 ("drivers/base/memory.c: don't store end_section_nr
in memory blocks"). Without this patch, kmem -n stops as the following:
crash> kmem -n
...
kmem: invalid structure member offset: memory_block_end_section_nr
FILE: memory.c LINE: 17426 FUNCTION: print_memory_block()
[./crash] error trace: 4b0b83 => 4b00fe => 5430e1 => 543063
543063: OFFSET_verify.part.28+51
5430e1: OFFSET_verify+49
4b00fe: print_memory_block+147
4b0b83: dump_memory_blocks+813
To fix this, use either memory_block_size_probed. If the symbol
doesn't exist, then use memory_block.end_section_nr. Either value
should be available on the kernel.
And the start section number is enough to get the memory block,
so change the output to show the start section number.
Signed-off-by: Masayoshi Mizuma <m.mizuma(a)jp.fujitsu.com>
---
help.c | 2 +-
memory.c | 42 +++++++++++++++++++++++++-----------------
2 files changed, 26 insertions(+), 18 deletions(-)
diff --git a/help.c b/help.c
index a5218a7..cfd46c3 100644
--- a/help.c
+++ b/help.c
@@ -7177,7 +7177,7 @@ char *help_kmem[] = {
" 6 ffff88003d4d90c0 ffffea0000000000 ffffea0000c00000 PM
196608",
" 7 ffff88003d4d90e0 ffffea0000000000 ffffea0000e00000 PM
229376",
" ",
-" MEM_BLOCK NAME PHYSICAL RANGE STATE
SECTIONS",
+" MEM_BLOCK NAME PHYSICAL RANGE STATE
START_SECTION_NO",
" ffff88003a707c00 memory0 0 - 7ffffff ONLINE 0",
" ffff88003a6e0000 memory1 8000000 - fffffff ONLINE 1",
" ffff88003a6e1000 memory2 10000000 - 17ffffff ONLINE 2",
diff --git a/memory.c b/memory.c
index fe82fac..a7ed915 100644
--- a/memory.c
+++ b/memory.c
@@ -17402,20 +17402,18 @@ fill_memory_block_name(ulong memblock, char *name)
}
static void
-fill_memory_block_srange(ulong start_sec, ulong end_sec, char *srange)
+fill_memory_block_srange(ulong start_sec, char *srange)
{
memset(srange, 0, sizeof(*srange) * BUFSIZE);
- if (start_sec == end_sec)
- sprintf(srange, "%lu", start_sec);
- else
- sprintf(srange, "%lu-%lu", start_sec, end_sec);
+ sprintf(srange, "%lu", start_sec);
}
static void
print_memory_block(ulong memory_block)
{
ulong start_sec, end_sec, start_pfn, end_pfn, nid;
+ ulong memblock_size, mbs, start_addr, end_addr;
char statebuf[BUFSIZE];
char srangebuf[BUFSIZE];
char name[BUFSIZE];
@@ -17430,15 +17428,25 @@ print_memory_block(ulong memory_block)
readmem(memory_block + OFFSET(memory_block_start_section_nr), KVADDR,
&start_sec, sizeof(void *), "memory_block start_section_nr",
FAULT_ON_ERROR);
- readmem(memory_block + OFFSET(memory_block_end_section_nr), KVADDR,
- &end_sec, sizeof(void *), "memory_block end_section_nr",
- FAULT_ON_ERROR);
- start_pfn = section_nr_to_pfn(start_sec);
- end_pfn = section_nr_to_pfn(end_sec + 1);
+ start_addr = pfn_to_phys(section_nr_to_pfn(start_sec));
+
+ if (symbol_exists("memory_block_size_probed")) {
+ memblock_size = symbol_value("memory_block_size_probed");
+ readmem(memblock_size, KVADDR,
+ &mbs, sizeof(ulong), "memory_block_size_probed",
+ FAULT_ON_ERROR);
+ end_addr = start_addr + mbs - 1;
+ } else {
+ readmem(memory_block + OFFSET(memory_block_end_section_nr), KVADDR,
+ &end_sec, sizeof(void *), "memory_block end_section_nr",
+ FAULT_ON_ERROR);
+ end_addr = pfn_to_phys(section_nr_to_pfn(end_sec + 1)) - 1;
+ }
+
fill_memory_block_state(memory_block, statebuf);
fill_memory_block_name(memory_block, name);
- fill_memory_block_srange(start_sec, end_sec, srangebuf);
+ fill_memory_block_srange(start_sec, srangebuf);
if (MEMBER_EXISTS("memory_block", "nid")) {
readmem(memory_block + OFFSET(memory_block_nid), KVADDR, &nid,
@@ -17448,9 +17456,9 @@ print_memory_block(ulong memory_block)
MKSTR(memory_block)),
mkstring(buf2, 12, CENTER, name),
mkstring(buf3, PADDR_PRLEN, RJUST|LONG_HEX,
- MKSTR(pfn_to_phys(start_pfn))),
+ MKSTR(start_addr)),
mkstring(buf4, PADDR_PRLEN, LJUST|LONG_HEX,
- MKSTR(pfn_to_phys(end_pfn) - 1)),
+ MKSTR(end_addr)),
mkstring(buf5, strlen("NODE"), CENTER|LONG_DEC,
MKSTR(nid)),
mkstring(buf6, strlen("CANCEL_OFFLINE"), LJUST,
@@ -17462,9 +17470,9 @@ print_memory_block(ulong memory_block)
MKSTR(memory_block)),
mkstring(buf2, 10, CENTER, name),
mkstring(buf3, PADDR_PRLEN, RJUST|LONG_HEX,
- MKSTR(pfn_to_phys(start_pfn))),
+ MKSTR(start_addr)),
mkstring(buf4, PADDR_PRLEN, LJUST|LONG_HEX,
- MKSTR(pfn_to_phys(end_pfn) - 1)),
+ MKSTR(end_addr)),
mkstring(buf5, strlen("CANCEL_OFFLINE"), LJUST,
statebuf),
mkstring(buf6, 12, LJUST, srangebuf));
@@ -17552,14 +17560,14 @@ dump_memory_blocks(int initialize)
mkstring(buf3, PADDR_PRLEN*2 + 2, CENTER, "PHYSICAL RANGE"),
mkstring(buf4, strlen("NODE"), CENTER, "NODE"),
mkstring(buf5, strlen("CANCEL_OFFLINE"), LJUST, "STATE"),
- mkstring(buf6, 12, LJUST, "SECTIONS"));
+ mkstring(buf6, 12, LJUST, "START_SECTION_NO"));
else
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, CENTER, "PHYSICAL RANGE"),
mkstring(buf4, strlen("CANCEL_OFFLINE"), LJUST, "STATE"),
- mkstring(buf5, 12, LJUST, "SECTIONS"));
+ mkstring(buf5, 12, LJUST, "START_SECTION_NO"));
fprintf(fp, "%s", mb_hdr);
for (i = 0; i < klistcnt; i++) {
--
2.18.1
--
Crash-utility mailing list
Crash-utility(a)redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility