git: 25e25d6f1b55 - stable/14 - vm_phys_avail_split(): Tolerate split requests at boundaries
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 08 Apr 2025 13:40:42 UTC
The branch stable/14 has been updated by olce:
URL: https://cgit.FreeBSD.org/src/commit/?id=25e25d6f1b55d9b48c1800dc1b5bd5e3d102a049
commit 25e25d6f1b55d9b48c1800dc1b5bd5e3d102a049
Author: Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2024-11-04 17:05:19 +0000
Commit: Olivier Certner <olce@FreeBSD.org>
CommitDate: 2025-04-08 13:38:21 +0000
vm_phys_avail_split(): Tolerate split requests at boundaries
Previously, such requests would lead to a panic. The only caller so far
(vm_phys_early_startup()) actually faces the case where some address can
be one of the chunk's boundaries and has to test it by hand. Moreover,
a later commit will introduce vm_phys_early_alloc_ex(), which will also
have to deal with such boundary cases.
Consequently, make this function handle boundaries by not splitting the
chunk and returning EJUSTRETURN instead of 0 to distinguish this case
from the "was split" result.
While here, expand the panic message when the address to split is not in
the passed chunk with available details.
Reviewed by: markj
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D48630
(cherry picked from commit e1499bfff8b8c128d7b3d330f95e0c67d7c1fa77)
---
sys/vm/vm_phys.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/sys/vm/vm_phys.c b/sys/vm/vm_phys.c
index 34a003fe0ab0..10ce7e15f12a 100644
--- a/sys/vm/vm_phys.c
+++ b/sys/vm/vm_phys.c
@@ -1671,7 +1671,13 @@ vm_phys_avail_size(int i)
}
/*
- * Split an entry at the address 'pa'. Return zero on success or errno.
+ * Split a chunk in phys_avail[] at the address 'pa'.
+ *
+ * 'pa' must be within a chunk (slots i and i + 1) or one of its boundaries.
+ * Returns zero on actual split, in which case the two new chunks occupy slots
+ * i to i + 3, else EJUSTRETURN if 'pa' was one of the boundaries (and no split
+ * actually occurred) else ENOSPC if there are not enough slots in phys_avail[]
+ * to represent the additional chunk caused by the split.
*/
static int
vm_phys_avail_split(vm_paddr_t pa, int i)
@@ -1679,8 +1685,12 @@ vm_phys_avail_split(vm_paddr_t pa, int i)
int cnt;
vm_phys_avail_check(i);
- if (pa <= phys_avail[i] || pa >= phys_avail[i + 1])
- panic("vm_phys_avail_split: invalid address");
+ if (pa < phys_avail[i] || pa > phys_avail[i + 1])
+ panic("%s: Address %#jx not in range at slot %d [%#jx;%#jx].",
+ __func__, (uintmax_t)pa, i,
+ (uintmax_t)phys_avail[i], (uintmax_t)phys_avail[i + 1]);
+ if (pa == phys_avail[i] || pa == phys_avail[i + 1])
+ return (EJUSTRETURN);
cnt = vm_phys_avail_count();
if (cnt >= PHYS_AVAIL_ENTRIES)
return (ENOSPC);
@@ -1842,12 +1852,10 @@ vm_phys_early_startup(void)
for (i = 0; mem_affinity[i].end != 0; i++) {
idx = vm_phys_avail_find(mem_affinity[i].start);
- if (idx != -1 &&
- phys_avail[idx] != mem_affinity[i].start)
+ if (idx != -1)
vm_phys_avail_split(mem_affinity[i].start, idx);
idx = vm_phys_avail_find(mem_affinity[i].end);
- if (idx != -1 &&
- phys_avail[idx] != mem_affinity[i].end)
+ if (idx != -1)
vm_phys_avail_split(mem_affinity[i].end, idx);
}
}