On 2023/12/19 0:01, 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 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 <[email protected]>
> ---
> v3 --> v4:
>       Use "files -p" to measure the time.
>       Dump it in "help -m"

Acked-by: Kazuhito Hagio <[email protected]>

Applied the 1/2 first,
https://github.com/crash-utility/crash/commit/19d3c56c9fca

and will apply this when a corresponding kernel patch gets applied.

Thanks,
Kazu

> ---
>   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 {
--
Crash-utility mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/
Contribution Guidelines: https://github.com/crash-utility/crash/wiki

Reply via email to