The branch main has been updated by olce:

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

commit e1499bfff8b8c128d7b3d330f95e0c67d7c1fa77
Author:     Olivier Certner <o...@freebsd.org>
AuthorDate: 2024-11-04 17:05:19 +0000
Commit:     Olivier Certner <o...@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);
                }
        }

Reply via email to