Move the code to handle the vm.blacklist tunable up a layer into

vm_page_startup().  As a result, we now only lookup the tunable once
instead of looking it up once for every physical page of memory in the
system.  This cuts out about a 1 second or so delay in boot on x86
systems.  The delay is much larger and more noticable on sun4v apparently.

Reported by:	kmacy
MFC after:	1 week
This commit is contained in:
jhb 2006-06-23 16:44:24 +00:00
parent bc2961a729
commit d4be78a6fa
2 changed files with 39 additions and 31 deletions

View File

@ -157,6 +157,36 @@ vm_set_page_size(void)
panic("vm_set_page_size: page size not a power of two");
}
/*
* vm_page_blacklist_lookup:
*
* See if a physical address in this page has been listed
* in the blacklist tunable. Entries in the tunable are
* separated by spaces or commas. If an invalid integer is
* encountered then the rest of the string is skipped.
*/
static int
vm_page_blacklist_lookup(char *list, vm_paddr_t pa)
{
vm_paddr_t bad;
char *cp, *pos;
for (pos = list; *pos != '\0'; pos = cp) {
bad = strtoq(pos, &cp, 0);
if (*cp != '\0') {
if (*cp == ' ' || *cp == ',') {
cp++;
if (cp == pos)
continue;
} else
break;
}
if (pa == trunc_page(bad))
return (1);
}
return (0);
}
/*
* vm_page_startup:
*
@ -177,6 +207,7 @@ vm_page_startup(vm_offset_t vaddr)
vm_paddr_t pa;
int nblocks;
vm_paddr_t last_pa;
char *list;
/* the biggest memory array is the second group of pages */
vm_paddr_t end;
@ -302,14 +333,21 @@ vm_page_startup(vm_offset_t vaddr)
*/
cnt.v_page_count = 0;
cnt.v_free_count = 0;
list = getenv("vm.blacklist");
for (i = 0; phys_avail[i + 1] && npages > 0; i += 2) {
pa = phys_avail[i];
last_pa = phys_avail[i + 1];
while (pa < last_pa && npages-- > 0) {
vm_pageq_add_new_page(pa);
if (list != NULL &&
vm_page_blacklist_lookup(list, pa))
printf("Skipping page with pa 0x%jx\n",
(uintmax_t)pa);
else
vm_pageq_add_new_page(pa);
pa += PAGE_SIZE;
}
}
freeenv(list);
return (vaddr);
}

View File

@ -191,37 +191,7 @@ vm_pageq_enqueue(int queue, vm_page_t m)
vm_page_t
vm_pageq_add_new_page(vm_paddr_t pa)
{
vm_paddr_t bad;
vm_page_t m;
char *cp, *list, *pos;
/*
* See if a physical address in this page has been listed
* in the blacklist tunable. Entries in the tunable are
* separated by spaces or commas. If an invalid integer is
* encountered then the rest of the string is skipped.
*/
if (testenv("vm.blacklist")) {
list = getenv("vm.blacklist");
for (pos = list; *pos != '\0'; pos = cp) {
bad = strtoq(pos, &cp, 0);
if (*cp != '\0') {
if (*cp == ' ' || *cp == ',') {
cp++;
if (cp == pos)
continue;
} else
break;
}
if (pa == trunc_page(bad)) {
printf("Skipping page with pa 0x%jx\n",
(uintmax_t)pa);
freeenv(list);
return (NULL);
}
}
freeenv(list);
}
atomic_add_int(&cnt.v_page_count, 1);
m = PHYS_TO_VM_PAGE(pa);