If the kernel exports the vmmemap then we can use that symbol in crash to optimize access. vmmemap is just an array of page structs after all. This patch tries to: 1.) Get the "vmemmap" from the vmcore file. If we can use the "vmemmap", we implement the arm64_vmemmap_is_page_ptr and set it to machdep->is_page_ptr. 2.) We implement the fast page_to_pfn code in arm64_vmemmap_is_page_ptr. 3.) Dump "vmemmap" in "help -v". Test result: Test the patch: "[PATCH v3] add "files -n" command for an inode" https://lists.crash-utility.osci.io/archives/list/ devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx/thread/CRLOQP534YKEQPTCXIWVDYK4NA7BOSUK/ Without the this patch: #files -n xxx (xxx is the inode of vmlinux which is 441M) This costed about 162 seconds. With the this patch: #files -n xxx (xxx is the inode of vmlinux which is 441M) This costed less then 1 second. Signed-off-by: Huang Shijie <shijie@xxxxxxxxxxxxxxxxxxxxxx> --- v2 --> v3: Use arm64_get_vmcoreinfo() to parse the "vmemmap" Dump it in "help -v" --- arm64.c | 25 +++++++++++++++++++++++++ defs.h | 1 + memory.c | 1 + 3 files changed, 27 insertions(+) diff --git a/arm64.c b/arm64.c index 57965c6..fd6e9f7 100644 --- a/arm64.c +++ b/arm64.c @@ -117,6 +117,28 @@ static void arm64_calc_kernel_start(void) ms->kimage_end = (sp ? sp->value : 0); } +static int +arm64_vmemmap_is_page_ptr(ulong addr, physaddr_t *phys) +{ + ulong size = SIZE(page); + ulong pfn, nr; + + + if (IS_SPARSEMEM() && (machdep->flags & VMEMMAP) && + (addr >= VMEMMAP_VADDR && addr <= VMEMMAP_END) && + !((addr - VMEMMAP_VADDR) % size)) { + + pfn = (addr - vt->vmemmap) / size; + nr = pfn_to_section_nr(pfn); + if (valid_section_nr(nr)) { + if (phys) + *phys = PTOB(pfn); + return TRUE; + } + } + return FALSE; +} + /* * Do all necessary machine-specific setup here. This is called several times * during initialization. @@ -382,6 +404,9 @@ arm64_init(int when) machdep->stacksize = ARM64_STACK_SIZE; machdep->flags |= VMEMMAP; + /* If vmemmap exists, it means kernel enabled CONFIG_SPARSEMEM_VMEMMAP */ + if (arm64_get_vmcoreinfo(&vt->vmemmap, "SYMBOL(vmemmap)", NUM_HEX)) + machdep->is_page_ptr = arm64_vmemmap_is_page_ptr; machdep->uvtop = arm64_uvtop; machdep->is_uvaddr = arm64_is_uvaddr; diff --git a/defs.h b/defs.h index 0558d13..bb775fd 100644 --- a/defs.h +++ b/defs.h @@ -2634,6 +2634,7 @@ struct vm_table { /* kernel VM-related data */ ulong max_mem_section_nr; ulong zero_paddr; ulong huge_zero_paddr; + ulong vmemmap; }; #define NODES (0x1) diff --git a/memory.c b/memory.c index 3e8da98..c878286 100644 --- a/memory.c +++ b/memory.c @@ -14104,6 +14104,7 @@ dump_vm_table(int verbose) fprintf(fp, " mem_sec: %lx\n", (ulong)vt->mem_sec); fprintf(fp, " mem_section: %lx\n", (ulong)vt->mem_section); fprintf(fp, " max_mem_section_nr: %ld\n", (ulong)vt->max_mem_section_nr); + fprintf(fp, " vmemmap: %lx\n", (ulong)vt->vmemmap); fprintf(fp, " ZONE_HIGHMEM: %d\n", vt->ZONE_HIGHMEM); fprintf(fp, "node_online_map_len: %d\n", vt->node_online_map_len); if (vt->node_online_map_len) { -- 2.40.1 -- Crash-utility mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxxxxxx https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/ Contribution Guidelines: https://github.com/crash-utility/crash/wiki