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.
This commit is contained in:
tnn 2024-01-13 09:44:42 +00:00
parent 1e917b8da1
commit ecaf2f4063
3 changed files with 27 additions and 25 deletions

View File

@ -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. * Copyright (c) 1997, 2019 The NetBSD Foundation, Inc.
@ -35,7 +35,7 @@
*/ */
#include <sys/cdefs.h> #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/param.h>
#include <sys/systm.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, 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) paddr_t alignment, paddr_t boundary, struct pglist *rlist)
{ {
signed int candidate, limit, candidateidx, end, idx, skip; long candidate, limit, candidateidx, end, idx;
int pagemask; int skip;
long pagemask;
bool second_pass; bool second_pass;
#ifdef DEBUG #ifdef DEBUG
paddr_t idxpa, lastidxpa; paddr_t idxpa, lastidxpa;
@ -138,9 +139,9 @@ uvm_pglistalloc_c_ps(uvm_physseg_t psi, int num, paddr_t low, paddr_t high,
* succeeded. * succeeded.
*/ */
alignment = atop(alignment); 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); 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); pagemask = ~((boundary >> PAGE_SHIFT) - 1);
skip = 0; skip = 0;
second_pass = false; second_pass = false;
@ -162,8 +163,8 @@ uvm_pglistalloc_c_ps(uvm_physseg_t psi, int num, paddr_t low, paddr_t high,
* is were we started. * is were we started.
*/ */
second_pass = true; second_pass = true;
candidate = roundup2(uimax(low, uvm_physseg_get_avail_start(psi)), alignment); candidate = roundup2(ulmax(low, uvm_physseg_get_avail_start(psi)), alignment);
limit = uimin(limit, uvm_physseg_get_avail_start(psi) + limit = ulmin(limit, uvm_physseg_get_avail_start(psi) +
uvm_physseg_get_start_hint(psi)); uvm_physseg_get_start_hint(psi));
skip = 0; skip = 0;
continue; continue;
@ -200,7 +201,7 @@ uvm_pglistalloc_c_ps(uvm_physseg_t psi, int num, paddr_t low, paddr_t high,
* Found a suitable starting page. See if the range is free. * Found a suitable starting page. See if the range is free.
*/ */
#ifdef PGALLOC_VERBOSE #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); __func__, psi, candidateidx, end, skip, alignment);
#endif #endif
/* /*
@ -283,7 +284,7 @@ uvm_pglistalloc_c_ps(uvm_physseg_t psi, int num, paddr_t low, paddr_t high,
uvm_physseg_get_avail_start(psi)); uvm_physseg_get_avail_start(psi));
KASSERTMSG(uvm_physseg_get_start_hint(psi) <= KASSERTMSG(uvm_physseg_get_start_hint(psi) <=
uvm_physseg_get_avail_end(psi) - uvm_physseg_get_avail_start(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, candidate + num,
uvm_physseg_get_start_hint(psi), uvm_physseg_get_start_hint(psi), uvm_physseg_get_start_hint(psi), uvm_physseg_get_start_hint(psi),
uvm_physseg_get_avail_end(psi), uvm_physseg_get_avail_start(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, uvm_pglistalloc_s_ps(uvm_physseg_t psi, int num, paddr_t low, paddr_t high,
struct pglist *rlist) struct pglist *rlist)
{ {
int todo, limit, candidate; int todo;
long limit, candidate;
struct vm_page *pg; struct vm_page *pg;
bool second_pass; bool second_pass;
#ifdef PGALLOC_VERBOSE #ifdef PGALLOC_VERBOSE
@ -546,9 +548,9 @@ uvm_pglistalloc_s_ps(uvm_physseg_t psi, int num, paddr_t low, paddr_t high,
return -1; return -1;
todo = num; 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)); 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)); pg = uvm_physseg_get_pg(psi, candidate - uvm_physseg_get_start(psi));
second_pass = false; second_pass = false;
@ -560,8 +562,8 @@ again:
break; break;
} }
second_pass = true; second_pass = true;
candidate = uimax(low, uvm_physseg_get_avail_start(psi)); candidate = ulmax(low, uvm_physseg_get_avail_start(psi));
limit = uimin(limit, uvm_physseg_get_avail_start(psi) + limit = ulmin(limit, uvm_physseg_get_avail_start(psi) +
uvm_physseg_get_start_hint(psi)); uvm_physseg_get_start_hint(psi));
pg = uvm_physseg_get_pg(psi, candidate - uvm_physseg_get_start(psi)); pg = uvm_physseg_get_pg(psi, candidate - uvm_physseg_get_start(psi));
goto again; goto again;
@ -571,10 +573,10 @@ again:
paddr_t cidx = 0; paddr_t cidx = 0;
const uvm_physseg_t bank = uvm_physseg_find(candidate, &cidx); const uvm_physseg_t bank = uvm_physseg_find(candidate, &cidx);
KDASSERTMSG(bank == psi, KDASSERTMSG(bank == psi,
"uvm_physseg_find(%#x) (%"PRIxPHYSSEG ") != psi %"PRIxPHYSSEG, "uvm_physseg_find(%#lx) (%"PRIxPHYSSEG ") != psi %"PRIxPHYSSEG,
candidate, bank, psi); candidate, bank, psi);
KDASSERTMSG(cidx == candidate - uvm_physseg_get_start(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)); candidate, cidx, candidate - uvm_physseg_get_start(psi));
} }
#endif #endif
@ -594,7 +596,7 @@ again:
uvm_physseg_set_start_hint(psi, candidate + 1 - uvm_physseg_get_avail_start(psi)); 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) - KASSERTMSG(uvm_physseg_get_start_hint(psi) <= uvm_physseg_get_avail_end(psi) -
uvm_physseg_get_avail_start(psi), uvm_physseg_get_avail_start(psi),
"%#x %u (%#x) <= %#"PRIxPADDR" - %#"PRIxPADDR" (%#"PRIxPADDR")", "%#lx %lu (%#lx) <= %#"PRIxPADDR" - %#"PRIxPADDR" (%#"PRIxPADDR")",
candidate + 1, candidate + 1,
uvm_physseg_get_start_hint(psi), uvm_physseg_get_start_hint(psi),
uvm_physseg_get_start_hint(psi), uvm_physseg_get_start_hint(psi),

View File

@ -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. * 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 */ paddr_t avail_end; /* (PF# of last free page in segment) +1 */
struct extent *ext; /* extent(9) structure to manage pgs[] */ struct extent *ext; /* extent(9) structure to manage pgs[] */
int free_list; /* which free list they belong on */ 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 #ifdef __HAVE_PMAP_PHYSSEG
struct pmap_physseg pmseg; /* pmap specific (MD) data */ struct pmap_physseg pmseg; /* pmap specific (MD) data */
#endif #endif
@ -1108,7 +1108,7 @@ uvm_physseg_get_free_list(uvm_physseg_t upm)
return HANDLE_TO_PHYSSEG_NODE(upm)->free_list; return HANDLE_TO_PHYSSEG_NODE(upm)->free_list;
} }
u_int u_long
uvm_physseg_get_start_hint(uvm_physseg_t upm) uvm_physseg_get_start_hint(uvm_physseg_t upm)
{ {
KASSERT(uvm_physseg_valid_p(upm)); KASSERT(uvm_physseg_valid_p(upm));
@ -1116,7 +1116,7 @@ uvm_physseg_get_start_hint(uvm_physseg_t upm)
} }
bool 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) if (uvm_physseg_valid_p(upm) == false)
return false; return false;

View File

@ -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. * Copyright (c) 2016 The NetBSD Foundation, Inc.
@ -106,8 +106,8 @@ struct pmap_physseg * uvm_physseg_get_pmseg(uvm_physseg_t);
#endif #endif
int uvm_physseg_get_free_list(uvm_physseg_t); int uvm_physseg_get_free_list(uvm_physseg_t);
u_int uvm_physseg_get_start_hint(uvm_physseg_t); u_long uvm_physseg_get_start_hint(uvm_physseg_t);
bool uvm_physseg_set_start_hint(uvm_physseg_t, u_int); bool uvm_physseg_set_start_hint(uvm_physseg_t, u_long);
/* /*
* Functions to help walk the list of segments. * Functions to help walk the list of segments.