Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Feb 2025 14:14:24 GMT
From:      Olivier Certner <olce@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: e1499bfff8b8 - main - vm_phys_avail_split(): Tolerate split requests at boundaries
Message-ID:  <202502191414.51JEEOHQ038195@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by olce:

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

commit e1499bfff8b8c128d7b3d330f95e0c67d7c1fa77
Author:     Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2024-11-04 17:05:19 +0000
Commit:     Olivier Certner <olce@FreeBSD.org>
CommitDate: 2025-02-19 14:13:27 +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
---
 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 e2b5a6e21365..82272be1a6c9 100644
--- a/sys/vm/vm_phys.c
+++ b/sys/vm/vm_phys.c
@@ -1854,7 +1854,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)
@@ -1862,8 +1868,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);
@@ -2025,12 +2035,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);
 		}
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202502191414.51JEEOHQ038195>