Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/vm_page.c
Show First 20 Lines • Show All 2,037 Lines • ▼ Show 20 Lines | |||||
* | * | ||||
* optional allocation flags: | * optional allocation flags: | ||||
* VM_ALLOC_COUNT(number) the number of additional pages that the caller | * VM_ALLOC_COUNT(number) the number of additional pages that the caller | ||||
* intends to allocate | * intends to allocate | ||||
* VM_ALLOC_WIRED wire the allocated page | * VM_ALLOC_WIRED wire the allocated page | ||||
* VM_ALLOC_ZERO prefer a zeroed page | * VM_ALLOC_ZERO prefer a zeroed page | ||||
*/ | */ | ||||
vm_page_t | vm_page_t | ||||
vm_page_alloc_freelist(int flind, int req) | vm_page_alloc_freelist(int freelist, int req) | ||||
{ | { | ||||
struct vm_domain_iterator vi; | struct vm_domain_iterator vi; | ||||
vm_page_t m; | vm_page_t m; | ||||
int domain, wait; | int domain, wait; | ||||
m = NULL; | m = NULL; | ||||
vm_policy_iterator_init(&vi); | vm_policy_iterator_init(&vi); | ||||
wait = req & (VM_ALLOC_WAITFAIL | VM_ALLOC_WAITOK); | wait = req & (VM_ALLOC_WAITFAIL | VM_ALLOC_WAITOK); | ||||
req &= ~wait; | req &= ~wait; | ||||
while (vm_domain_iterator_run(&vi, &domain) == 0) { | while (vm_domain_iterator_run(&vi, &domain) == 0) { | ||||
if (vm_domain_iterator_isdone(&vi)) | if (vm_domain_iterator_isdone(&vi)) | ||||
req |= wait; | req |= wait; | ||||
m = vm_page_alloc_freelist_domain(domain, flind, req); | m = vm_page_alloc_freelist_domain(domain, freelist, req); | ||||
if (m != NULL) | if (m != NULL) | ||||
break; | break; | ||||
} | } | ||||
vm_policy_iterator_finish(&vi); | vm_policy_iterator_finish(&vi); | ||||
return (m); | return (m); | ||||
} | } | ||||
vm_page_t | vm_page_t | ||||
vm_page_alloc_freelist_domain(int domain, int flind, int req) | vm_page_alloc_freelist_domain(int domain, int freelist, int req) | ||||
{ | { | ||||
vm_page_t m; | vm_page_t m; | ||||
u_int flags, free_count; | u_int flags, free_count; | ||||
int req_class; | int req_class; | ||||
req_class = req & VM_ALLOC_CLASS_MASK; | req_class = req & VM_ALLOC_CLASS_MASK; | ||||
/* | /* | ||||
* The page daemon is allowed to dig deeper into the free page list. | * The page daemon is allowed to dig deeper into the free page list. | ||||
*/ | */ | ||||
if (curproc == pageproc && req_class != VM_ALLOC_INTERRUPT) | if (curproc == pageproc && req_class != VM_ALLOC_INTERRUPT) | ||||
req_class = VM_ALLOC_SYSTEM; | req_class = VM_ALLOC_SYSTEM; | ||||
/* | /* | ||||
* Do not allocate reserved pages unless the req has asked for it. | * Do not allocate reserved pages unless the req has asked for it. | ||||
*/ | */ | ||||
again: | again: | ||||
mtx_lock(&vm_page_queue_free_mtx); | mtx_lock(&vm_page_queue_free_mtx); | ||||
if (vm_cnt.v_free_count > vm_cnt.v_free_reserved || | if (vm_cnt.v_free_count > vm_cnt.v_free_reserved || | ||||
(req_class == VM_ALLOC_SYSTEM && | (req_class == VM_ALLOC_SYSTEM && | ||||
vm_cnt.v_free_count > vm_cnt.v_interrupt_free_min) || | vm_cnt.v_free_count > vm_cnt.v_interrupt_free_min) || | ||||
(req_class == VM_ALLOC_INTERRUPT && | (req_class == VM_ALLOC_INTERRUPT && | ||||
vm_cnt.v_free_count > 0)) | vm_cnt.v_free_count > 0)) | ||||
m = vm_phys_alloc_freelist_pages(domain, flind, | m = vm_phys_alloc_freelist_pages(domain, freelist, | ||||
VM_FREEPOOL_DIRECT, 0); | VM_FREEPOOL_DIRECT, 0); | ||||
if (m == NULL) { | if (m == NULL) { | ||||
if (vm_page_alloc_fail(NULL, req)) | if (vm_page_alloc_fail(NULL, req)) | ||||
goto again; | goto again; | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
free_count = vm_phys_freecnt_adj(m, -1); | free_count = vm_phys_freecnt_adj(m, -1); | ||||
mtx_unlock(&vm_page_queue_free_mtx); | mtx_unlock(&vm_page_queue_free_mtx); | ||||
▲ Show 20 Lines • Show All 1,905 Lines • Show Last 20 Lines |