Module Name: src Committed By: tnn Date: Sat Jan 13 09:44:42 UTC 2024
Modified Files: src/sys/uvm: uvm_pglist.c uvm_physseg.c uvm_physseg.h Log Message: uvm: change type of uvm_physseg.start_hint from u_int to u_long Avoids assertion failure in uvm_pglistalloc_s_ps() with large paddrs. PR kern/57683. To generate a diff of this commit: cvs rdiff -u -r1.90 -r1.91 src/sys/uvm/uvm_pglist.c cvs rdiff -u -r1.19 -r1.20 src/sys/uvm/uvm_physseg.c cvs rdiff -u -r1.8 -r1.9 src/sys/uvm/uvm_physseg.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/uvm/uvm_pglist.c diff -u src/sys/uvm/uvm_pglist.c:1.90 src/sys/uvm/uvm_pglist.c:1.91 --- src/sys/uvm/uvm_pglist.c:1.90 Tue Dec 21 08:27:49 2021 +++ src/sys/uvm/uvm_pglist.c Sat Jan 13 09:44:42 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_pglist.c,v 1.90 2021/12/21 08:27:49 skrll Exp $ */ +/* $NetBSD: uvm_pglist.c,v 1.91 2024/01/13 09:44:42 tnn Exp $ */ /*- * Copyright (c) 1997, 2019 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvm_pglist.c,v 1.90 2021/12/21 08:27:49 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_pglist.c,v 1.91 2024/01/13 09:44:42 tnn Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -112,8 +112,9 @@ static int uvm_pglistalloc_c_ps(uvm_physseg_t psi, int num, paddr_t low, paddr_t high, paddr_t alignment, paddr_t boundary, struct pglist *rlist) { - signed int candidate, limit, candidateidx, end, idx, skip; - int pagemask; + long candidate, limit, candidateidx, end, idx; + int skip; + long pagemask; bool second_pass; #ifdef DEBUG paddr_t idxpa, lastidxpa; @@ -138,9 +139,9 @@ uvm_pglistalloc_c_ps(uvm_physseg_t psi, * succeeded. */ alignment = atop(alignment); - candidate = roundup2(uimax(low, uvm_physseg_get_avail_start(psi) + + candidate = roundup2(ulmax(low, uvm_physseg_get_avail_start(psi) + uvm_physseg_get_start_hint(psi)), alignment); - limit = uimin(high, uvm_physseg_get_avail_end(psi)); + limit = ulmin(high, uvm_physseg_get_avail_end(psi)); pagemask = ~((boundary >> PAGE_SHIFT) - 1); skip = 0; second_pass = false; @@ -162,8 +163,8 @@ uvm_pglistalloc_c_ps(uvm_physseg_t psi, * is were we started. */ second_pass = true; - candidate = roundup2(uimax(low, uvm_physseg_get_avail_start(psi)), alignment); - limit = uimin(limit, uvm_physseg_get_avail_start(psi) + + candidate = roundup2(ulmax(low, uvm_physseg_get_avail_start(psi)), alignment); + limit = ulmin(limit, uvm_physseg_get_avail_start(psi) + uvm_physseg_get_start_hint(psi)); skip = 0; continue; @@ -200,7 +201,7 @@ uvm_pglistalloc_c_ps(uvm_physseg_t psi, * Found a suitable starting page. See if the range is free. */ #ifdef PGALLOC_VERBOSE - printf("%s: psi=%d candidate=%#x end=%#x skip=%#x, align=%#"PRIxPADDR, + printf("%s: psi=%d candidate=%#lx end=%#lx skip=%#x, align=%#"PRIxPADDR, __func__, psi, candidateidx, end, skip, alignment); #endif /* @@ -283,7 +284,7 @@ uvm_pglistalloc_c_ps(uvm_physseg_t psi, uvm_physseg_get_avail_start(psi)); KASSERTMSG(uvm_physseg_get_start_hint(psi) <= uvm_physseg_get_avail_end(psi) - uvm_physseg_get_avail_start(psi), - "%x %u (%#x) <= %#"PRIxPADDR" - %#"PRIxPADDR" (%#"PRIxPADDR")", + "%lx %lu (%#lx) <= %#"PRIxPADDR" - %#"PRIxPADDR" (%#"PRIxPADDR")", candidate + num, uvm_physseg_get_start_hint(psi), uvm_physseg_get_start_hint(psi), uvm_physseg_get_avail_end(psi), uvm_physseg_get_avail_start(psi), @@ -523,7 +524,8 @@ static int uvm_pglistalloc_s_ps(uvm_physseg_t psi, int num, paddr_t low, paddr_t high, struct pglist *rlist) { - int todo, limit, candidate; + int todo; + long limit, candidate; struct vm_page *pg; bool second_pass; #ifdef PGALLOC_VERBOSE @@ -546,9 +548,9 @@ uvm_pglistalloc_s_ps(uvm_physseg_t psi, return -1; todo = num; - candidate = uimax(low, uvm_physseg_get_avail_start(psi) + + candidate = ulmax(low, uvm_physseg_get_avail_start(psi) + uvm_physseg_get_start_hint(psi)); - limit = uimin(high, uvm_physseg_get_avail_end(psi)); + limit = ulmin(high, uvm_physseg_get_avail_end(psi)); pg = uvm_physseg_get_pg(psi, candidate - uvm_physseg_get_start(psi)); second_pass = false; @@ -560,8 +562,8 @@ again: break; } second_pass = true; - candidate = uimax(low, uvm_physseg_get_avail_start(psi)); - limit = uimin(limit, uvm_physseg_get_avail_start(psi) + + candidate = ulmax(low, uvm_physseg_get_avail_start(psi)); + limit = ulmin(limit, uvm_physseg_get_avail_start(psi) + uvm_physseg_get_start_hint(psi)); pg = uvm_physseg_get_pg(psi, candidate - uvm_physseg_get_start(psi)); goto again; @@ -571,10 +573,10 @@ again: paddr_t cidx = 0; const uvm_physseg_t bank = uvm_physseg_find(candidate, &cidx); KDASSERTMSG(bank == psi, - "uvm_physseg_find(%#x) (%"PRIxPHYSSEG ") != psi %"PRIxPHYSSEG, + "uvm_physseg_find(%#lx) (%"PRIxPHYSSEG ") != psi %"PRIxPHYSSEG, candidate, bank, psi); KDASSERTMSG(cidx == candidate - uvm_physseg_get_start(psi), - "uvm_physseg_find(%#x): %#"PRIxPADDR" != off %"PRIxPADDR, + "uvm_physseg_find(%#lx): %#"PRIxPADDR" != off %"PRIxPADDR, candidate, cidx, candidate - uvm_physseg_get_start(psi)); } #endif @@ -594,7 +596,7 @@ again: uvm_physseg_set_start_hint(psi, candidate + 1 - uvm_physseg_get_avail_start(psi)); KASSERTMSG(uvm_physseg_get_start_hint(psi) <= uvm_physseg_get_avail_end(psi) - uvm_physseg_get_avail_start(psi), - "%#x %u (%#x) <= %#"PRIxPADDR" - %#"PRIxPADDR" (%#"PRIxPADDR")", + "%#lx %lu (%#lx) <= %#"PRIxPADDR" - %#"PRIxPADDR" (%#"PRIxPADDR")", candidate + 1, uvm_physseg_get_start_hint(psi), uvm_physseg_get_start_hint(psi), Index: src/sys/uvm/uvm_physseg.c diff -u src/sys/uvm/uvm_physseg.c:1.19 src/sys/uvm/uvm_physseg.c:1.20 --- src/sys/uvm/uvm_physseg.c:1.19 Sat Sep 23 18:20:20 2023 +++ src/sys/uvm/uvm_physseg.c Sat Jan 13 09:44:42 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_physseg.c,v 1.19 2023/09/23 18:20:20 ad Exp $ */ +/* $NetBSD: uvm_physseg.c,v 1.20 2024/01/13 09:44:42 tnn Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -100,7 +100,7 @@ struct uvm_physseg { paddr_t avail_end; /* (PF# of last free page in segment) +1 */ struct extent *ext; /* extent(9) structure to manage pgs[] */ int free_list; /* which free list they belong on */ - u_int start_hint; /* start looking for free pages here */ + u_long start_hint; /* start looking for free pages here */ #ifdef __HAVE_PMAP_PHYSSEG struct pmap_physseg pmseg; /* pmap specific (MD) data */ #endif @@ -1108,7 +1108,7 @@ uvm_physseg_get_free_list(uvm_physseg_t return HANDLE_TO_PHYSSEG_NODE(upm)->free_list; } -u_int +u_long uvm_physseg_get_start_hint(uvm_physseg_t upm) { KASSERT(uvm_physseg_valid_p(upm)); @@ -1116,7 +1116,7 @@ uvm_physseg_get_start_hint(uvm_physseg_t } bool -uvm_physseg_set_start_hint(uvm_physseg_t upm, u_int start_hint) +uvm_physseg_set_start_hint(uvm_physseg_t upm, u_long start_hint) { if (uvm_physseg_valid_p(upm) == false) return false; Index: src/sys/uvm/uvm_physseg.h diff -u src/sys/uvm/uvm_physseg.h:1.8 src/sys/uvm/uvm_physseg.h:1.9 --- src/sys/uvm/uvm_physseg.h:1.8 Mon Jan 2 20:08:32 2017 +++ src/sys/uvm/uvm_physseg.h Sat Jan 13 09:44:42 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_physseg.h,v 1.8 2017/01/02 20:08:32 cherry Exp $ */ +/* $NetBSD: uvm_physseg.h,v 1.9 2024/01/13 09:44:42 tnn Exp $ */ /*- * Copyright (c) 2016 The NetBSD Foundation, Inc. @@ -106,8 +106,8 @@ struct pmap_physseg * uvm_physseg_get_pm #endif int uvm_physseg_get_free_list(uvm_physseg_t); -u_int uvm_physseg_get_start_hint(uvm_physseg_t); -bool uvm_physseg_set_start_hint(uvm_physseg_t, u_int); +u_long uvm_physseg_get_start_hint(uvm_physseg_t); +bool uvm_physseg_set_start_hint(uvm_physseg_t, u_long); /* * Functions to help walk the list of segments.