Changeset View
Changeset View
Standalone View
Standalone View
head/sys/vm/vm_page.c
Show First 20 Lines • Show All 3,167 Lines • ▼ Show 20 Lines | |||||
* VM_ALLOC_SYSTEM system *really* needs the pages | * VM_ALLOC_SYSTEM system *really* needs the pages | ||||
* | * | ||||
* The caller must always specify that the pages are to be busied and/or | * The caller must always specify that the pages are to be busied and/or | ||||
* wired. | * wired. | ||||
* | * | ||||
* optional allocation flags: | * optional allocation flags: | ||||
* VM_ALLOC_IGN_SBUSY do not sleep on soft busy pages | * VM_ALLOC_IGN_SBUSY do not sleep on soft busy pages | ||||
* VM_ALLOC_NOBUSY do not exclusive busy the page | * VM_ALLOC_NOBUSY do not exclusive busy the page | ||||
* VM_ALLOC_NOWAIT do not sleep | |||||
* VM_ALLOC_SBUSY set page to sbusy state | * VM_ALLOC_SBUSY set page to sbusy state | ||||
* VM_ALLOC_WIRED wire the pages | * VM_ALLOC_WIRED wire the pages | ||||
* VM_ALLOC_ZERO zero and validate any invalid pages | * VM_ALLOC_ZERO zero and validate any invalid pages | ||||
* | * | ||||
* This routine may sleep. | * If VM_ALLOC_NOWAIT is not specified, this routine may sleep. Otherwise, it | ||||
* may return a partial prefix of the requested range. | |||||
*/ | */ | ||||
void | int | ||||
vm_page_grab_pages(vm_object_t object, vm_pindex_t pindex, int allocflags, | vm_page_grab_pages(vm_object_t object, vm_pindex_t pindex, int allocflags, | ||||
vm_page_t *ma, int count) | vm_page_t *ma, int count) | ||||
{ | { | ||||
vm_page_t m; | vm_page_t m; | ||||
int i; | int i; | ||||
bool sleep; | bool sleep; | ||||
VM_OBJECT_ASSERT_WLOCKED(object); | VM_OBJECT_ASSERT_WLOCKED(object); | ||||
KASSERT(((u_int)allocflags >> VM_ALLOC_COUNT_SHIFT) == 0, | KASSERT(((u_int)allocflags >> VM_ALLOC_COUNT_SHIFT) == 0, | ||||
("vm_page_grap_pages: VM_ALLOC_COUNT() is not allowed")); | ("vm_page_grap_pages: VM_ALLOC_COUNT() is not allowed")); | ||||
KASSERT((allocflags & VM_ALLOC_NOBUSY) == 0 || | KASSERT((allocflags & VM_ALLOC_NOBUSY) == 0 || | ||||
(allocflags & VM_ALLOC_WIRED) != 0, | (allocflags & VM_ALLOC_WIRED) != 0, | ||||
("vm_page_grab_pages: the pages must be busied or wired")); | ("vm_page_grab_pages: the pages must be busied or wired")); | ||||
KASSERT((allocflags & VM_ALLOC_SBUSY) == 0 || | KASSERT((allocflags & VM_ALLOC_SBUSY) == 0 || | ||||
(allocflags & VM_ALLOC_IGN_SBUSY) != 0, | (allocflags & VM_ALLOC_IGN_SBUSY) != 0, | ||||
("vm_page_grab_pages: VM_ALLOC_SBUSY/IGN_SBUSY mismatch")); | ("vm_page_grab_pages: VM_ALLOC_SBUSY/IGN_SBUSY mismatch")); | ||||
if (count == 0) | if (count == 0) | ||||
return; | return (0); | ||||
i = 0; | i = 0; | ||||
retrylookup: | retrylookup: | ||||
m = vm_page_lookup(object, pindex + i); | m = vm_page_lookup(object, pindex + i); | ||||
for (; i < count; i++) { | for (; i < count; i++) { | ||||
if (m != NULL) { | if (m != NULL) { | ||||
sleep = (allocflags & VM_ALLOC_IGN_SBUSY) != 0 ? | sleep = (allocflags & VM_ALLOC_IGN_SBUSY) != 0 ? | ||||
vm_page_xbusied(m) : vm_page_busied(m); | vm_page_xbusied(m) : vm_page_busied(m); | ||||
if (sleep) { | if (sleep) { | ||||
if ((allocflags & VM_ALLOC_NOWAIT) != 0) | |||||
break; | |||||
/* | /* | ||||
* Reference the page before unlocking and | * Reference the page before unlocking and | ||||
* sleeping so that the page daemon is less | * sleeping so that the page daemon is less | ||||
* likely to reclaim it. | * likely to reclaim it. | ||||
*/ | */ | ||||
vm_page_aflag_set(m, PGA_REFERENCED); | vm_page_aflag_set(m, PGA_REFERENCED); | ||||
vm_page_lock(m); | vm_page_lock(m); | ||||
VM_OBJECT_WUNLOCK(object); | VM_OBJECT_WUNLOCK(object); | ||||
Show All 11 Lines | if (m != NULL) { | ||||
VM_ALLOC_SBUSY)) == 0) | VM_ALLOC_SBUSY)) == 0) | ||||
vm_page_xbusy(m); | vm_page_xbusy(m); | ||||
if ((allocflags & VM_ALLOC_SBUSY) != 0) | if ((allocflags & VM_ALLOC_SBUSY) != 0) | ||||
vm_page_sbusy(m); | vm_page_sbusy(m); | ||||
} else { | } else { | ||||
m = vm_page_alloc(object, pindex + i, (allocflags & | m = vm_page_alloc(object, pindex + i, (allocflags & | ||||
~VM_ALLOC_IGN_SBUSY) | VM_ALLOC_COUNT(count - i)); | ~VM_ALLOC_IGN_SBUSY) | VM_ALLOC_COUNT(count - i)); | ||||
if (m == NULL) { | if (m == NULL) { | ||||
if ((allocflags & VM_ALLOC_NOWAIT) != 0) | |||||
break; | |||||
VM_OBJECT_WUNLOCK(object); | VM_OBJECT_WUNLOCK(object); | ||||
VM_WAIT; | VM_WAIT; | ||||
VM_OBJECT_WLOCK(object); | VM_OBJECT_WLOCK(object); | ||||
goto retrylookup; | goto retrylookup; | ||||
} | } | ||||
} | } | ||||
if (m->valid == 0 && (allocflags & VM_ALLOC_ZERO) != 0) { | if (m->valid == 0 && (allocflags & VM_ALLOC_ZERO) != 0) { | ||||
if ((m->flags & PG_ZERO) == 0) | if ((m->flags & PG_ZERO) == 0) | ||||
pmap_zero_page(m); | pmap_zero_page(m); | ||||
m->valid = VM_PAGE_BITS_ALL; | m->valid = VM_PAGE_BITS_ALL; | ||||
} | } | ||||
ma[i] = m; | ma[i] = m; | ||||
m = vm_page_next(m); | m = vm_page_next(m); | ||||
} | } | ||||
return (i); | |||||
} | } | ||||
/* | /* | ||||
* Mapping function for valid or dirty bits in a page. | * Mapping function for valid or dirty bits in a page. | ||||
* | * | ||||
* Inputs are required to range within a page. | * Inputs are required to range within a page. | ||||
*/ | */ | ||||
vm_page_bits_t | vm_page_bits_t | ||||
▲ Show 20 Lines • Show All 499 Lines • Show Last 20 Lines |