File crash-arm64-Add-support-for-vmemmap-symbol-in-vmcoreinfo.patch of Package crash.41263
From 18bf18cf2e6bcd84e22c3c5a285fafbc84d0655c Mon Sep 17 00:00:00 2001
From: Huang Shijie <shijie@os.amperecomputing.com>
Date: Mon, 18 Dec 2023 23:01:40 +0800
Subject: [PATCH] arm64: Add support for vmemmap symbol in vmcoreinfo
With kernel commit d3246b6ee42a ("crash_core: export vmemmap when
CONFIG_SPARSEMEM_VMEMMAP is enabled") in Linux 6.9-rc1 and later, we can
use the vmemmap symbol in vmcoreinfo to optimize machdep->is_page_ptr.
vmemmap is just an array of struct page after all.
This patch tries to:
1.) Get the "vmemmap" from the vmcore file. If it's available,
arm64_vmemmap_is_page_ptr is set to machdep->is_page_ptr.
2.) Implement the fast page_to_pfn code in arm64_vmemmap_is_page_ptr.
3.) Dump it in "help -m".
With the patch, "files -p" command for the inode of 441M vmlinux takes
only 3 seconds, while 185 seconds without the patch.
Signed-off-by: Huang Shijie <shijie@os.amperecomputing.com>
---
arm64.c | 26 ++++++++++++++++++++++++++
defs.h | 1 +
2 files changed, 27 insertions(+)
diff --git a/arm64.c b/arm64.c
index 6ab10ca..af0e0d7 100644
--- a/arm64.c
+++ b/arm64.c
@@ -152,6 +152,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.
@@ -420,6 +442,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;
@@ -1136,6 +1161,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 98650e8..3cb8e63 100644
--- a/defs.h
+++ b/defs.h
@@ -3499,6 +3499,7 @@ struct machine_specific {
ulong CONFIG_ARM64_KERNELPACMASK;
ulong physvirt_offset;
ulong struct_page_size;
+ ulong vmemmap;
};
struct arm64_stackframe {
--
2.43.0