git: 5794f8c75ef1 - stable/13 - minidump: De-duplicate is_dumpable()

From: Mitchell Horne <mhorne_at_FreeBSD.org>
Date: Fri, 15 Oct 2021 15:26:11 UTC
The branch stable/13 has been updated by mhorne:

URL: https://cgit.FreeBSD.org/src/commit/?id=5794f8c75ef15047e22c14fe81c7793d0d2c35e7

commit 5794f8c75ef15047e22c14fe81c7793d0d2c35e7
Author:     Mitchell Horne <mhorne@FreeBSD.org>
AuthorDate: 2021-09-29 17:30:11 +0000
Commit:     Mitchell Horne <mhorne@FreeBSD.org>
CommitDate: 2021-10-15 15:20:48 +0000

    minidump: De-duplicate is_dumpable()
    
    The function is identical in each minidump implementation, so move it to
    vm_phys.c. The only slight exception is powerpc where the function was
    public, for use in moea64_scan_pmap().
    
    Reviewed by:    kib, markj, imp (earlier version)
    MFC after:      2 weeks
    Sponsored by:   Juniper Networks, Inc.
    Sponsored by:   Klara, Inc.
    Differential Revision:  https://reviews.freebsd.org/D31884
    
    (cherry picked from commit 31991a5a45857e88c29dec422e0b8d6f68f8877b)
---
 sys/amd64/amd64/minidump_machdep.c     | 25 +++++--------------------
 sys/amd64/amd64/uma_machdep.c          |  1 +
 sys/arm/arm/minidump_machdep.c         | 19 ++-----------------
 sys/arm64/arm64/minidump_machdep.c     | 23 ++++-------------------
 sys/arm64/arm64/uma_machdep.c          |  1 +
 sys/i386/i386/minidump_machdep_base.c  | 21 +++------------------
 sys/mips/mips/minidump_machdep.c       | 21 +++------------------
 sys/mips/mips/uma_machdep.c            |  1 +
 sys/powerpc/aim/mmu_oea64.c            |  4 ++--
 sys/powerpc/include/md_var.h           |  1 -
 sys/powerpc/powerpc/minidump_machdep.c | 17 +----------------
 sys/powerpc/powerpc/uma_machdep.c      |  1 +
 sys/riscv/riscv/minidump_machdep.c     | 22 +++-------------------
 sys/riscv/riscv/uma_machdep.c          |  1 +
 sys/vm/vm_phys.c                       | 19 +++++++++++++++++++
 sys/vm/vm_phys.h                       |  1 +
 16 files changed, 48 insertions(+), 130 deletions(-)

diff --git a/sys/amd64/amd64/minidump_machdep.c b/sys/amd64/amd64/minidump_machdep.c
index ea8220157083..7c54c423bbaf 100644
--- a/sys/amd64/amd64/minidump_machdep.c
+++ b/sys/amd64/amd64/minidump_machdep.c
@@ -66,21 +66,6 @@ static int dump_retry_count = 5;
 SYSCTL_INT(_machdep, OID_AUTO, dump_retry_count, CTLFLAG_RWTUN,
     &dump_retry_count, 0, "Number of times dump has to retry before bailing out");
 
-static int
-is_dumpable(vm_paddr_t pa)
-{
-	vm_page_t m;
-	int i;
-
-	if ((m = vm_phys_paddr_to_vm_page(pa)) != NULL)
-		return ((m->flags & PG_NODUMP) == 0);
-	for (i = 0; dump_avail[i] != 0 || dump_avail[i + 1] != 0; i += 2) {
-		if (pa >= dump_avail[i] && pa < dump_avail[i + 1])
-			return (1);
-	}
-	return (0);
-}
-
 #define PG2MB(pgs) (((pgs) + (1 << 8) - 1) >> 8)
 
 static int
@@ -256,7 +241,7 @@ minidumpsys(struct dumperinfo *di)
 			va += NBPDP;
 			pa = pdp[i] & PG_PS_FRAME;
 			for (n = 0; n < NPDEPG * NPTEPG; n++) {
-				if (is_dumpable(pa))
+				if (vm_phys_is_dumpable(pa))
 					dump_add_page(pa);
 				pa += PAGE_SIZE;
 			}
@@ -274,7 +259,7 @@ minidumpsys(struct dumperinfo *di)
 				/* This is an entire 2M page. */
 				pa = pd[j] & PG_PS_FRAME;
 				for (k = 0; k < NPTEPG; k++) {
-					if (is_dumpable(pa))
+					if (vm_phys_is_dumpable(pa))
 						dump_add_page(pa);
 					pa += PAGE_SIZE;
 				}
@@ -283,7 +268,7 @@ minidumpsys(struct dumperinfo *di)
 
 			pa = pd[j] & PG_FRAME;
 			/* set bit for this PTE page */
-			if (is_dumpable(pa))
+			if (vm_phys_is_dumpable(pa))
 				dump_add_page(pa);
 			/* and for each valid page in this 2MB block */
 			pt = (uint64_t *)PHYS_TO_DMAP(pd[j] & PG_FRAME);
@@ -291,7 +276,7 @@ minidumpsys(struct dumperinfo *di)
 				if ((pt[k] & PG_V) == 0)
 					continue;
 				pa = pt[k] & PG_FRAME;
-				if (is_dumpable(pa))
+				if (vm_phys_is_dumpable(pa))
 					dump_add_page(pa);
 			}
 		}
@@ -304,7 +289,7 @@ minidumpsys(struct dumperinfo *di)
 	dumpsize += round_page(BITSET_SIZE(vm_page_dump_pages));
 	VM_PAGE_DUMP_FOREACH(pa) {
 		/* Clear out undumpable pages now if needed */
-		if (is_dumpable(pa)) {
+		if (vm_phys_is_dumpable(pa)) {
 			dumpsize += PAGE_SIZE;
 		} else {
 			dump_drop_page(pa);
diff --git a/sys/amd64/amd64/uma_machdep.c b/sys/amd64/amd64/uma_machdep.c
index d080abeefdcc..2fc981f23c83 100644
--- a/sys/amd64/amd64/uma_machdep.c
+++ b/sys/amd64/amd64/uma_machdep.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm.h>
 #include <vm/vm_param.h>
 #include <vm/vm_page.h>
+#include <vm/vm_phys.h>
 #include <vm/vm_dumpset.h>
 #include <vm/uma.h>
 #include <vm/uma_int.h>
diff --git a/sys/arm/arm/minidump_machdep.c b/sys/arm/arm/minidump_machdep.c
index c5f9cb58302e..f760d774bfbb 100644
--- a/sys/arm/arm/minidump_machdep.c
+++ b/sys/arm/arm/minidump_machdep.c
@@ -65,21 +65,6 @@ static size_t fragsz;
 static void *dump_va;
 static uint64_t counter, progress;
 
-static int
-is_dumpable(vm_paddr_t pa)
-{
-	vm_page_t m;
-	int i;
-
-	if ((m = vm_phys_paddr_to_vm_page(pa)) != NULL)
-		return ((m->flags & PG_NODUMP) == 0);
-	for (i = 0; dump_avail[i] != 0 || dump_avail[i + 1] != 0; i += 2) {
-		if (pa >= dump_avail[i] && pa < dump_avail[i + 1])
-			return (1);
-	}
-	return (0);
-}
-
 #define PG2MB(pgs) (((pgs) + (1 << 8) - 1) >> 8)
 
 static int
@@ -202,7 +187,7 @@ minidumpsys(struct dumperinfo *di)
 	ptesize = 0;
 	for (va = KERNBASE; va < kernel_vm_end; va += PAGE_SIZE) {
 		pa = pmap_dump_kextract(va, NULL);
-		if (pa != 0 && is_dumpable(pa))
+		if (pa != 0 && vm_phys_is_dumpable(pa))
 			dump_add_page(pa);
 		ptesize += sizeof(pt2_entry_t);
 	}
@@ -214,7 +199,7 @@ minidumpsys(struct dumperinfo *di)
 	dumpsize += round_page(BITSET_SIZE(vm_page_dump_pages));
 	VM_PAGE_DUMP_FOREACH(pa) {
 		/* Clear out undumpable pages now if needed */
-		if (is_dumpable(pa))
+		if (vm_phys_is_dumpable(pa))
 			dumpsize += PAGE_SIZE;
 		else
 			dump_drop_page(pa);
diff --git a/sys/arm64/arm64/minidump_machdep.c b/sys/arm64/arm64/minidump_machdep.c
index 1dd40806669b..98d0b50be4c6 100644
--- a/sys/arm64/arm64/minidump_machdep.c
+++ b/sys/arm64/arm64/minidump_machdep.c
@@ -66,21 +66,6 @@ static size_t counter, progress, dumpsize;
 
 static uint64_t tmpbuffer[Ln_ENTRIES];
 
-static int
-is_dumpable(vm_paddr_t pa)
-{
-	vm_page_t m;
-	int i;
-
-	if ((m = vm_phys_paddr_to_vm_page(pa)) != NULL)
-		return ((m->flags & PG_NODUMP) == 0);
-	for (i = 0; dump_avail[i] != 0 || dump_avail[i + 1] != 0; i += 2) {
-		if (pa >= dump_avail[i] && pa < dump_avail[i + 1])
-			return (1);
-	}
-	return (0);
-}
-
 static int
 blk_flush(struct dumperinfo *di)
 {
@@ -226,14 +211,14 @@ minidumpsys(struct dumperinfo *di)
 			pa = *l1 & ~ATTR_MASK;
 			for (i = 0; i < Ln_ENTRIES * Ln_ENTRIES;
 			    i++, pa += PAGE_SIZE)
-				if (is_dumpable(pa))
+				if (vm_phys_is_dumpable(pa))
 					dump_add_page(pa);
 			pmapsize += (Ln_ENTRIES - 1) * PAGE_SIZE;
 			va += L1_SIZE - L2_SIZE;
 		} else if ((*l2 & ATTR_DESCR_MASK) == L2_BLOCK) {
 			pa = *l2 & ~ATTR_MASK;
 			for (i = 0; i < Ln_ENTRIES; i++, pa += PAGE_SIZE) {
-				if (is_dumpable(pa))
+				if (vm_phys_is_dumpable(pa))
 					dump_add_page(pa);
 			}
 		} else if ((*l2 & ATTR_DESCR_MASK) == L2_TABLE) {
@@ -241,7 +226,7 @@ minidumpsys(struct dumperinfo *di)
 				if ((l3[i] & ATTR_DESCR_MASK) != L3_PAGE)
 					continue;
 				pa = l3[i] & ~ATTR_MASK;
-				if (is_dumpable(pa))
+				if (vm_phys_is_dumpable(pa))
 					dump_add_page(pa);
 			}
 		}
@@ -253,7 +238,7 @@ minidumpsys(struct dumperinfo *di)
 	dumpsize += round_page(sizeof(dump_avail));
 	dumpsize += round_page(BITSET_SIZE(vm_page_dump_pages));
 	VM_PAGE_DUMP_FOREACH(pa) {
-		if (is_dumpable(pa))
+		if (vm_phys_is_dumpable(pa))
 			dumpsize += PAGE_SIZE;
 		else
 			dump_drop_page(pa);
diff --git a/sys/arm64/arm64/uma_machdep.c b/sys/arm64/arm64/uma_machdep.c
index c848edbe32be..3ef3dd3cc9e9 100644
--- a/sys/arm64/arm64/uma_machdep.c
+++ b/sys/arm64/arm64/uma_machdep.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm.h>
 #include <vm/vm_param.h>
 #include <vm/vm_page.h>
+#include <vm/vm_phys.h>
 #include <vm/vm_dumpset.h>
 #include <vm/uma.h>
 #include <vm/uma_int.h>
diff --git a/sys/i386/i386/minidump_machdep_base.c b/sys/i386/i386/minidump_machdep_base.c
index e2b4234eba11..b8e9e4884552 100644
--- a/sys/i386/i386/minidump_machdep_base.c
+++ b/sys/i386/i386/minidump_machdep_base.c
@@ -62,21 +62,6 @@ static size_t fragsz;
 static void *dump_va;
 static uint64_t counter, progress;
 
-static int
-is_dumpable(vm_paddr_t pa)
-{
-	vm_page_t m;
-	int i;
-
-	if ((m = vm_phys_paddr_to_vm_page(pa)) != NULL)
-		return ((m->flags & PG_NODUMP) == 0);
-	for (i = 0; dump_avail[i] != 0 || dump_avail[i + 1] != 0; i += 2) {
-		if (pa >= dump_avail[i] && pa < dump_avail[i + 1])
-			return (1);
-	}
-	return (0);
-}
-
 #define PG2MB(pgs) (((pgs) + (1 << 8) - 1) >> 8)
 
 static int
@@ -203,7 +188,7 @@ minidumpsys(struct dumperinfo *di)
 			/* This is an entire 2M page. */
 			pa = pd[j] & PG_PS_FRAME;
 			for (k = 0; k < NPTEPG; k++) {
-				if (is_dumpable(pa))
+				if (vm_phys_is_dumpable(pa))
 					dump_add_page(pa);
 				pa += PAGE_SIZE;
 			}
@@ -215,7 +200,7 @@ minidumpsys(struct dumperinfo *di)
 			for (k = 0; k < NPTEPG; k++) {
 				if ((pt[k] & PG_V) == PG_V) {
 					pa = pt[k] & PG_FRAME;
-					if (is_dumpable(pa))
+					if (vm_phys_is_dumpable(pa))
 						dump_add_page(pa);
 				}
 			}
@@ -231,7 +216,7 @@ minidumpsys(struct dumperinfo *di)
 	dumpsize += round_page(BITSET_SIZE(vm_page_dump_pages));
 	VM_PAGE_DUMP_FOREACH(pa) {
 		/* Clear out undumpable pages now if needed */
-		if (is_dumpable(pa)) {
+		if (vm_phys_is_dumpable(pa)) {
 			dumpsize += PAGE_SIZE;
 		} else {
 			dump_drop_page(pa);
diff --git a/sys/mips/mips/minidump_machdep.c b/sys/mips/mips/minidump_machdep.c
index e1edfa9ad5d3..d35b1fd53068 100644
--- a/sys/mips/mips/minidump_machdep.c
+++ b/sys/mips/mips/minidump_machdep.c
@@ -64,21 +64,6 @@ static char tmpbuffer[PAGE_SIZE] __aligned(sizeof(uint64_t));
 
 extern pd_entry_t *kernel_segmap;
 
-static int
-is_dumpable(vm_paddr_t pa)
-{
-	vm_page_t m;
-	int i;
-
-	if ((m = vm_phys_paddr_to_vm_page(pa)) != NULL)
-		return ((m->flags & PG_NODUMP) == 0);
-	for (i = 0; dump_avail[i] != 0 || dump_avail[i + 1] != 0; i += 2) {
-		if (pa >= dump_avail[i] && pa < dump_avail[i + 1])
-			return (1);
-	}
-	return (0);
-}
-
 static struct {
 	int min_per;
 	int max_per;
@@ -189,7 +174,7 @@ minidumpsys(struct dumperinfo *di)
 		for (i = 0; i < NPTEPG; i++) {
 			if (pte_test(&pte[i], PTE_V)) {
 				pa = TLBLO_PTE_TO_PA(pte[i]);
-				if (is_dumpable(pa))
+				if (vm_phys_is_dumpable(pa))
 					dump_add_page(pa);
 			}
 		}
@@ -200,7 +185,7 @@ minidumpsys(struct dumperinfo *di)
 	 * and pages allocated by pmap_steal reside
 	 */
 	for (pa = 0; pa < phys_avail[0]; pa += PAGE_SIZE) {
-		if (is_dumpable(pa))
+		if (vm_phys_is_dumpable(pa))
 			dump_add_page(pa);
 	}
 
@@ -211,7 +196,7 @@ minidumpsys(struct dumperinfo *di)
 	dumpsize += round_page(BITSET_SIZE(vm_page_dump_pages));
 	VM_PAGE_DUMP_FOREACH(pa) {
 		/* Clear out undumpable pages now if needed */
-		if (is_dumpable(pa))
+		if (vm_phys_is_dumpable(pa))
 			dumpsize += PAGE_SIZE;
 		else
 			dump_drop_page(pa);
diff --git a/sys/mips/mips/uma_machdep.c b/sys/mips/mips/uma_machdep.c
index faf70b20b748..5b57447edd6a 100644
--- a/sys/mips/mips/uma_machdep.c
+++ b/sys/mips/mips/uma_machdep.c
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_param.h>
 #include <vm/vm_page.h>
 #include <vm/vm_pageout.h>
+#include <vm/vm_phys.h>
 #include <vm/vm_dumpset.h>
 #include <vm/uma.h>
 #include <vm/uma_int.h>
diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
index 0e9b15661758..3faa3d0752b8 100644
--- a/sys/powerpc/aim/mmu_oea64.c
+++ b/sys/powerpc/aim/mmu_oea64.c
@@ -3369,11 +3369,11 @@ moea64_scan_pmap()
 		if (va & PVO_LARGE) {
 			pa_end = pa + lpsize;
 			for (; pa < pa_end; pa += PAGE_SIZE) {
-				if (is_dumpable(pa))
+				if (vm_phys_is_dumpable(pa))
 					dump_add_page(pa);
 			}
 		} else {
-			if (is_dumpable(pa))
+			if (vm_phys_is_dumpable(pa))
 				dump_add_page(pa);
 		}
 	}
diff --git a/sys/powerpc/include/md_var.h b/sys/powerpc/include/md_var.h
index da9232313ffb..ab5f9e33a5bb 100644
--- a/sys/powerpc/include/md_var.h
+++ b/sys/powerpc/include/md_var.h
@@ -44,7 +44,6 @@ extern	int	szsigcode64, szsigcode64_elfv2;
 
 struct	dumperinfo;
 int	minidumpsys(struct dumperinfo *);
-int	is_dumpable(vm_paddr_t);
 #endif
 
 extern	long	Maxmem;
diff --git a/sys/powerpc/powerpc/minidump_machdep.c b/sys/powerpc/powerpc/minidump_machdep.c
index e049f2debcfa..e4d85fe95ed6 100644
--- a/sys/powerpc/powerpc/minidump_machdep.c
+++ b/sys/powerpc/powerpc/minidump_machdep.c
@@ -91,21 +91,6 @@ static size_t counter, dumpsize, progress;
 /* Handle chunked writes. */
 static size_t fragsz;
 
-int
-is_dumpable(vm_paddr_t pa)
-{
-	vm_page_t m;
-	int i;
-
-	if ((m = vm_phys_paddr_to_vm_page(pa)) != NULL)
-		return ((m->flags & PG_NODUMP) == 0);
-	for (i = 0; dump_avail[i] != 0 || dump_avail[i + 1] != 0; i += 2) {
-		if (pa >= dump_avail[i] && pa < dump_avail[i + 1])
-			return (1);
-	}
-	return (0);
-}
-
 static void
 pmap_kenter_temporary(vm_offset_t va, vm_paddr_t pa)
 {
@@ -276,7 +261,7 @@ retry:
 	dumpsize += pmapsize;
 	VM_PAGE_DUMP_FOREACH(pa) {
 		/* Clear out undumpable pages now if needed */
-		if (is_dumpable(pa))
+		if (vm_phys_is_dumpable(pa))
 			dumpsize += PAGE_SIZE;
 		else
 			dump_drop_page(pa);
diff --git a/sys/powerpc/powerpc/uma_machdep.c b/sys/powerpc/powerpc/uma_machdep.c
index 43e2a86456fe..a1769f61d671 100644
--- a/sys/powerpc/powerpc/uma_machdep.c
+++ b/sys/powerpc/powerpc/uma_machdep.c
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_param.h>
 #include <vm/pmap.h>
 #include <vm/vm_page.h>
+#include <vm/vm_phys.h>
 #include <vm/vm_dumpset.h>
 #include <vm/uma.h>
 #include <vm/uma_int.h>
diff --git a/sys/riscv/riscv/minidump_machdep.c b/sys/riscv/riscv/minidump_machdep.c
index 2c5e27b6274f..bcedfbdf2fb2 100644
--- a/sys/riscv/riscv/minidump_machdep.c
+++ b/sys/riscv/riscv/minidump_machdep.c
@@ -99,22 +99,6 @@ report_progress(size_t progress, size_t dumpsize)
 	}
 }
 
-static bool
-is_dumpable(vm_paddr_t pa)
-{
-	vm_page_t m;
-	int i;
-
-	if ((m = vm_phys_paddr_to_vm_page(pa)) != NULL)
-		return ((m->flags & PG_NODUMP) == 0);
-
-	for (i = 0; dump_avail[i] != 0 || dump_avail[i + 1] != 0; i += 2) {
-		if (pa >= dump_avail[i] && pa < dump_avail[i + 1])
-			return (true);
-	}
-	return (false);
-}
-
 static int
 blk_flush(struct dumperinfo *di)
 {
@@ -241,7 +225,7 @@ retry:
 		if ((*l2 & PTE_RWX) != 0) {
 			pa = (*l2 >> PTE_PPN1_S) << L2_SHIFT;
 			for (i = 0; i < Ln_ENTRIES; i++, pa += PAGE_SIZE) {
-				if (is_dumpable(pa))
+				if (vm_phys_is_dumpable(pa))
 					dump_add_page(pa);
 			}
 		} else {
@@ -249,7 +233,7 @@ retry:
 				if ((l3[i] & PTE_V) == 0)
 					continue;
 				pa = (l3[i] >> PTE_PPN0_S) * PAGE_SIZE;
-				if (is_dumpable(pa))
+				if (vm_phys_is_dumpable(pa))
 					dump_add_page(pa);
 			}
 		}
@@ -262,7 +246,7 @@ retry:
 	dumpsize += round_page(BITSET_SIZE(vm_page_dump_pages));
 	VM_PAGE_DUMP_FOREACH(pa) {
 		/* Clear out undumpable pages now if needed */
-		if (is_dumpable(pa))
+		if (vm_phys_is_dumpable(pa))
 			dumpsize += PAGE_SIZE;
 		else
 			dump_drop_page(pa);
diff --git a/sys/riscv/riscv/uma_machdep.c b/sys/riscv/riscv/uma_machdep.c
index 6b563ea8ab0c..f1725fde4699 100644
--- a/sys/riscv/riscv/uma_machdep.c
+++ b/sys/riscv/riscv/uma_machdep.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm.h>
 #include <vm/vm_param.h>
 #include <vm/vm_page.h>
+#include <vm/vm_phys.h>
 #include <vm/vm_dumpset.h>
 #include <vm/uma.h>
 #include <vm/uma_int.h>
diff --git a/sys/vm/vm_phys.c b/sys/vm/vm_phys.c
index c8f98a0b4695..b0aaa822211f 100644
--- a/sys/vm/vm_phys.c
+++ b/sys/vm/vm_phys.c
@@ -1593,6 +1593,25 @@ vm_phys_avail_split(vm_paddr_t pa, int i)
 	return (0);
 }
 
+/*
+ * Check if a given physical address can be included as part of a crash dump.
+ */
+bool
+vm_phys_is_dumpable(vm_paddr_t pa)
+{
+	vm_page_t m;
+	int i;
+
+	if ((m = vm_phys_paddr_to_vm_page(pa)) != NULL)
+		return ((m->flags & PG_NODUMP) == 0);
+
+	for (i = 0; dump_avail[i] != 0 || dump_avail[i + 1] != 0; i += 2) {
+		if (pa >= dump_avail[i] && pa < dump_avail[i + 1])
+			return (true);
+	}
+	return (false);
+}
+
 void
 vm_phys_early_add_seg(vm_paddr_t start, vm_paddr_t end)
 {
diff --git a/sys/vm/vm_phys.h b/sys/vm/vm_phys.h
index a650d7dbc380..d10eb96f938f 100644
--- a/sys/vm/vm_phys.h
+++ b/sys/vm/vm_phys.h
@@ -87,6 +87,7 @@ vm_paddr_t vm_phys_early_alloc(int domain, size_t alloc_size);
 void vm_phys_early_startup(void);
 int vm_phys_avail_largest(void);
 vm_paddr_t vm_phys_avail_size(int i);
+bool vm_phys_is_dumpable(vm_paddr_t pa);
 
 static inline int
 vm_phys_domain(vm_paddr_t pa)