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

openSUSE Build Service is sponsored by