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.
@ -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, int num, paddr_t low, paddr_t high,
* 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, int num, paddr_t low, paddr_t high,
* 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, int num, paddr_t low, paddr_t high,
* 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, int num, paddr_t low, paddr_t high,
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, int num, paddr_t low, paddr_t high,
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),

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.
@ -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 upm)
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 upm)
}
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;

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.
@ -106,8 +106,8 @@ struct pmap_physseg * uvm_physseg_get_pmseg(uvm_physseg_t);
#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.