Begin and end the initialization of pvzone in pmap_init().
Previously, pvzone's initialization was split between pmap_init() and pmap_init2(). This split initialization was the underlying cause of some UMA panics during initialization. Specifically, if the UMA boot pages was exhausted before the pvzone was fully initialized, then UMA, through no fault of its own, would use an inappropriate back-end allocator leading to a panic. (Previously, as a workaround, we have increased the UMA boot pages.) Fortunately, there is no longer any reason that pvzone's initialization cannot be completed in pmap_init(). Eliminate a check for whether pv_entry_high_water has been initialized or not from get_pv_entry(). Since pvzone's initialization is completed in pmap_init(), this check is no longer needed. Use cnt.v_page_count, the actual count of available physical pages, instead of vm_page_array_size to compute the maximum number of pv entries. Introduce the vm.pmap.pv_entries tunable on alpha and ia64. Eliminate some unnecessary white space. Discussed with: tegge (item #1) Tested by: marcel (ia64)
This commit is contained in:
parent
a5f7708723
commit
e9cb1037da
@ -186,8 +186,6 @@ __FBSDID("$FreeBSD$");
|
||||
#define PMAP_DIAGNOSTIC
|
||||
#endif
|
||||
|
||||
#define MINPV 2048
|
||||
|
||||
#if 0
|
||||
#define PMAP_DIAGNOSTIC
|
||||
#define PMAP_DEBUG
|
||||
@ -572,28 +570,24 @@ pmap_page_init(vm_page_t m)
|
||||
void
|
||||
pmap_init(void)
|
||||
{
|
||||
int shpgperproc = PMAP_SHPGPERPROC;
|
||||
|
||||
/*
|
||||
* init the pv free list
|
||||
* Initialize the address space (zone) for the pv entries. Set a
|
||||
* high water mark so that the system can recover from excessive
|
||||
* numbers of pv entries.
|
||||
*/
|
||||
pvzone = uma_zcreate("PV ENTRY", sizeof (struct pv_entry), NULL, NULL,
|
||||
pvzone = uma_zcreate("PV ENTRY", sizeof(struct pv_entry), NULL, NULL,
|
||||
NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE);
|
||||
uma_prealloc(pvzone, MINPV);
|
||||
TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc);
|
||||
pv_entry_max = shpgperproc * maxproc + cnt.v_page_count;
|
||||
TUNABLE_INT_FETCH("vm.pmap.pv_entries", &pv_entry_max);
|
||||
pv_entry_high_water = 9 * (pv_entry_max / 10);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the address space (zone) for the pv_entries. Set a
|
||||
* high water mark so that the system can recover from excessive
|
||||
* numbers of pv entries.
|
||||
*/
|
||||
void
|
||||
pmap_init2()
|
||||
{
|
||||
int shpgperproc = PMAP_SHPGPERPROC;
|
||||
|
||||
TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc);
|
||||
pv_entry_max = shpgperproc * maxproc + vm_page_array_size;
|
||||
pv_entry_high_water = 9 * (pv_entry_max / 10);
|
||||
}
|
||||
|
||||
|
||||
@ -1313,8 +1307,7 @@ static pv_entry_t
|
||||
get_pv_entry(void)
|
||||
{
|
||||
pv_entry_count++;
|
||||
if (pv_entry_high_water &&
|
||||
(pv_entry_count > pv_entry_high_water) &&
|
||||
if ((pv_entry_count > pv_entry_high_water) &&
|
||||
(pmap_pagedaemon_waken == 0)) {
|
||||
pmap_pagedaemon_waken = 1;
|
||||
wakeup (&vm_pages_needed);
|
||||
|
@ -152,8 +152,6 @@ __FBSDID("$FreeBSD$");
|
||||
#define PMAP_DIAGNOSTIC
|
||||
#endif
|
||||
|
||||
#define MINPV 2048
|
||||
|
||||
#if !defined(PMAP_DIAGNOSTIC)
|
||||
#define PMAP_INLINE __inline
|
||||
#else
|
||||
@ -566,33 +564,28 @@ pmap_page_init(vm_page_t m)
|
||||
*/
|
||||
void
|
||||
pmap_init(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* init the pv free list
|
||||
*/
|
||||
pvzone = uma_zcreate("PV ENTRY", sizeof (struct pv_entry), NULL, NULL,
|
||||
NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE);
|
||||
uma_prealloc(pvzone, MINPV);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the address space (zone) for the pv_entries. Set a
|
||||
* high water mark so that the system can recover from excessive
|
||||
* numbers of pv entries.
|
||||
*/
|
||||
void
|
||||
pmap_init2()
|
||||
{
|
||||
int shpgperproc = PMAP_SHPGPERPROC;
|
||||
|
||||
/*
|
||||
* Initialize the address space (zone) for the pv entries. Set a
|
||||
* high water mark so that the system can recover from excessive
|
||||
* numbers of pv entries.
|
||||
*/
|
||||
pvzone = uma_zcreate("PV ENTRY", sizeof(struct pv_entry), NULL, NULL,
|
||||
NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE);
|
||||
TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc);
|
||||
pv_entry_max = shpgperproc * maxproc + vm_page_array_size;
|
||||
pv_entry_max = shpgperproc * maxproc + cnt.v_page_count;
|
||||
TUNABLE_INT_FETCH("vm.pmap.pv_entries", &pv_entry_max);
|
||||
pv_entry_high_water = 9 * (pv_entry_max / 10);
|
||||
uma_zone_set_obj(pvzone, &pvzone_obj, pv_entry_max);
|
||||
}
|
||||
|
||||
void
|
||||
pmap_init2()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/***************************************************
|
||||
* Low level helper routines.....
|
||||
@ -1442,8 +1435,7 @@ static pv_entry_t
|
||||
get_pv_entry(void)
|
||||
{
|
||||
pv_entry_count++;
|
||||
if (pv_entry_high_water &&
|
||||
(pv_entry_count > pv_entry_high_water) &&
|
||||
if ((pv_entry_count > pv_entry_high_water) &&
|
||||
(pmap_pagedaemon_waken == 0)) {
|
||||
pmap_pagedaemon_waken = 1;
|
||||
wakeup (&vm_pages_needed);
|
||||
|
@ -156,8 +156,6 @@ __FBSDID("$FreeBSD$");
|
||||
#define PMAP_DIAGNOSTIC
|
||||
#endif
|
||||
|
||||
#define MINPV 2048
|
||||
|
||||
#if !defined(PMAP_DIAGNOSTIC)
|
||||
#define PMAP_INLINE __inline
|
||||
#else
|
||||
@ -473,13 +471,20 @@ pmap_pdpt_allocf(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
|
||||
void
|
||||
pmap_init(void)
|
||||
{
|
||||
int shpgperproc = PMAP_SHPGPERPROC;
|
||||
|
||||
/*
|
||||
* init the pv free list
|
||||
* Initialize the address space (zone) for the pv entries. Set a
|
||||
* high water mark so that the system can recover from excessive
|
||||
* numbers of pv entries.
|
||||
*/
|
||||
pvzone = uma_zcreate("PV ENTRY", sizeof (struct pv_entry), NULL, NULL,
|
||||
pvzone = uma_zcreate("PV ENTRY", sizeof(struct pv_entry), NULL, NULL,
|
||||
NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE);
|
||||
uma_prealloc(pvzone, MINPV);
|
||||
TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc);
|
||||
pv_entry_max = shpgperproc * maxproc + cnt.v_page_count;
|
||||
TUNABLE_INT_FETCH("vm.pmap.pv_entries", &pv_entry_max);
|
||||
pv_entry_high_water = 9 * (pv_entry_max / 10);
|
||||
uma_zone_set_obj(pvzone, &pvzone_obj, pv_entry_max);
|
||||
|
||||
#ifdef PAE
|
||||
pdptzone = uma_zcreate("PDPT", NPGPTD * sizeof(pdpt_entry_t), NULL,
|
||||
@ -489,21 +494,9 @@ pmap_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the address space (zone) for the pv_entries. Set a
|
||||
* high water mark so that the system can recover from excessive
|
||||
* numbers of pv entries.
|
||||
*/
|
||||
void
|
||||
pmap_init2()
|
||||
{
|
||||
int shpgperproc = PMAP_SHPGPERPROC;
|
||||
|
||||
TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc);
|
||||
pv_entry_max = shpgperproc * maxproc + vm_page_array_size;
|
||||
TUNABLE_INT_FETCH("vm.pmap.pv_entries", &pv_entry_max);
|
||||
pv_entry_high_water = 9 * (pv_entry_max / 10);
|
||||
uma_zone_set_obj(pvzone, &pvzone_obj, pv_entry_max);
|
||||
}
|
||||
|
||||
|
||||
@ -1444,8 +1437,7 @@ static pv_entry_t
|
||||
get_pv_entry(void)
|
||||
{
|
||||
pv_entry_count++;
|
||||
if (pv_entry_high_water &&
|
||||
(pv_entry_count > pv_entry_high_water) &&
|
||||
if ((pv_entry_count > pv_entry_high_water) &&
|
||||
(pmap_pagedaemon_waken == 0)) {
|
||||
pmap_pagedaemon_waken = 1;
|
||||
wakeup (&vm_pages_needed);
|
||||
|
@ -124,8 +124,6 @@ MALLOC_DEFINE(M_PMAP, "PMAP", "PMAP Structures");
|
||||
#define PMAP_SHPGPERPROC 200
|
||||
#endif
|
||||
|
||||
#define MINPV 2048 /* Preallocate at least this many */
|
||||
|
||||
#if !defined(DIAGNOSTIC)
|
||||
#define PMAP_INLINE __inline
|
||||
#else
|
||||
@ -518,32 +516,27 @@ pmap_page_init(vm_page_t m)
|
||||
void
|
||||
pmap_init(void)
|
||||
{
|
||||
int shpgperproc = PMAP_SHPGPERPROC;
|
||||
|
||||
/*
|
||||
* Init the pv free list and the PTE free list.
|
||||
* Initialize the address space (zone) for the pv entries. Set a
|
||||
* high water mark so that the system can recover from excessive
|
||||
* numbers of pv entries.
|
||||
*/
|
||||
pvzone = uma_zcreate("PV ENTRY", sizeof (struct pv_entry),
|
||||
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM|UMA_ZONE_NOFREE);
|
||||
uma_prealloc(pvzone, MINPV);
|
||||
pvzone = uma_zcreate("PV ENTRY", sizeof(struct pv_entry), NULL, NULL,
|
||||
NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE);
|
||||
TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc);
|
||||
pv_entry_max = shpgperproc * maxproc + cnt.v_page_count;
|
||||
TUNABLE_INT_FETCH("vm.pmap.pv_entries", &pv_entry_max);
|
||||
pv_entry_high_water = 9 * (pv_entry_max / 10);
|
||||
|
||||
ptezone = uma_zcreate("PT ENTRY", sizeof (struct ia64_lpte),
|
||||
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM|UMA_ZONE_NOFREE);
|
||||
uma_prealloc(ptezone, MINPV);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the address space (zone) for the pv_entries. Set a
|
||||
* high water mark so that the system can recover from excessive
|
||||
* numbers of pv entries.
|
||||
*/
|
||||
void
|
||||
pmap_init2()
|
||||
{
|
||||
int shpgperproc = PMAP_SHPGPERPROC;
|
||||
|
||||
TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc);
|
||||
pv_entry_max = shpgperproc * maxproc + vm_page_array_size;
|
||||
pv_entry_high_water = 9 * (pv_entry_max / 10);
|
||||
}
|
||||
|
||||
|
||||
@ -821,8 +814,7 @@ static pv_entry_t
|
||||
get_pv_entry(void)
|
||||
{
|
||||
pv_entry_count++;
|
||||
if (pv_entry_high_water &&
|
||||
(pv_entry_count > pv_entry_high_water) &&
|
||||
if ((pv_entry_count > pv_entry_high_water) &&
|
||||
(pmap_pagedaemon_waken == 0)) {
|
||||
pmap_pagedaemon_waken = 1;
|
||||
wakeup (&vm_pages_needed);
|
||||
|
Loading…
x
Reference in New Issue
Block a user