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 it in "help -m" Test result: Without the this patch: #files -p xxx > /dev/null (xxx is the inode of vmlinux which is 441M) This costed about 185 seconds. With the this patch: #files -p xxx > /dev/null (xxx is the inode of vmlinux which is 441M) This costed 3 seconds. Signed-off-by: Huang Shijie <shijie@xxxxxxxxxxxxxxxxxxxxxx> --- v3 --> v4: Use "files -p" to measure the time. Dump it in "help -m" --- arm64.c | 26 ++++++++++++++++++++++++++ defs.h | 1 + 2 files changed, 27 insertions(+) diff --git a/arm64.c b/arm64.c index 57965c6..fc4ba64 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 - machdep->machspec->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(&ms->vmemmap, "SYMBOL(vmemmap)", NUM_HEX)) + machdep->is_page_ptr = arm64_vmemmap_is_page_ptr; machdep->uvtop = arm64_uvtop; machdep->is_uvaddr = arm64_is_uvaddr; @@ -1096,6 +1121,7 @@ arm64_dump_machdep_table(ulong arg) fprintf(fp, " vmemmap_vaddr: %016lx\n", ms->vmemmap_vaddr); fprintf(fp, " vmemmap_end: %016lx\n", ms->vmemmap_end); if (machdep->flags & NEW_VMEMMAP) { + fprintf(fp, " vmemmap: %016lx\n", ms->vmemmap); fprintf(fp, " kimage_text: %016lx\n", ms->kimage_text); fprintf(fp, " kimage_end: %016lx\n", ms->kimage_end); fprintf(fp, " kimage_voffset: %016lx\n", ms->kimage_voffset); diff --git a/defs.h b/defs.h index 0558d13..3431a32 100644 --- a/defs.h +++ b/defs.h @@ -3486,6 +3486,7 @@ struct machine_specific { ulong CONFIG_ARM64_KERNELPACMASK; ulong physvirt_offset; ulong struct_page_size; + ulong vmemmap; }; struct arm64_stackframe { -- 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