On 2023/12/14 16:15, Huang Shijie wrote: > 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. Thanks for the update. btw, how does the patch work for "files -p" or "kmem -s" in performance? Maybe "> /dev/null" is better. It would be better to use an existing command, if possible. > > 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; could you move this to machine_specific? The variables related to vmemmap have been there so far and not all architectures will use this. Thanks, Kazu > }; > > #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) { -- 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