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:
parent
1e917b8da1
commit
ecaf2f4063
|
@ -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),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue