Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/vm_kern.c
| Show First 20 Lines • Show All 524 Lines • ▼ Show 20 Lines | |||||
| * | * | ||||
| * Allocate physical pages from the specified domain for the specified | * Allocate physical pages from the specified domain for the specified | ||||
| * virtual address range. | * virtual address range. | ||||
| */ | */ | ||||
| int | int | ||||
| kmem_back_domain(int domain, vm_object_t object, vm_offset_t addr, | kmem_back_domain(int domain, vm_object_t object, vm_offset_t addr, | ||||
| vm_size_t size, int flags) | vm_size_t size, int flags) | ||||
| { | { | ||||
| struct pctrie_iter pages; | |||||
| vm_offset_t offset, i; | vm_offset_t offset, i; | ||||
| vm_page_t m, mpred; | vm_page_t m, mpred; | ||||
| vm_prot_t prot; | vm_prot_t prot; | ||||
| int pflags; | int pflags; | ||||
| KASSERT(object == kernel_object, | KASSERT(object == kernel_object, | ||||
| ("kmem_back_domain: only supports kernel object.")); | ("kmem_back_domain: only supports kernel object.")); | ||||
| offset = addr - VM_MIN_KERNEL_ADDRESS; | offset = addr - VM_MIN_KERNEL_ADDRESS; | ||||
| pflags = malloc2vm_flags(flags) | VM_ALLOC_WIRED; | pflags = malloc2vm_flags(flags) | VM_ALLOC_WIRED; | ||||
| pflags &= ~(VM_ALLOC_NOWAIT | VM_ALLOC_WAITOK | VM_ALLOC_WAITFAIL); | pflags &= ~(VM_ALLOC_NOWAIT | VM_ALLOC_WAITOK | VM_ALLOC_WAITFAIL); | ||||
| if (flags & M_WAITOK) | if (flags & M_WAITOK) | ||||
| pflags |= VM_ALLOC_WAITFAIL; | pflags |= VM_ALLOC_WAITFAIL; | ||||
| prot = (flags & M_EXEC) != 0 ? VM_PROT_ALL : VM_PROT_RW; | prot = (flags & M_EXEC) != 0 ? VM_PROT_ALL : VM_PROT_RW; | ||||
| i = 0; | i = 0; | ||||
| VM_OBJECT_WLOCK(object); | VM_OBJECT_WLOCK(object); | ||||
| vm_page_iter_init(&pages, object); | |||||
| retry: | retry: | ||||
| mpred = vm_radix_lookup_le(&object->rtree, atop(offset + i)); | mpred = vm_radix_iter_lookup_le(&pages, atop(offset + i)); | ||||
| for (; i < size; i += PAGE_SIZE, mpred = m) { | for (; i < size; i += PAGE_SIZE, mpred = m) { | ||||
| m = vm_page_alloc_domain_after(object, atop(offset + i), | m = vm_page_alloc_domain(&pages, object, atop(offset + i), | ||||
| domain, pflags, mpred); | domain, pflags, mpred); | ||||
| /* | /* | ||||
| * Ran out of space, free everything up and return. Don't need | * Ran out of space, free everything up and return. Don't need | ||||
| * to lock page queues here as we know that the pages we got | * to lock page queues here as we know that the pages we got | ||||
| * aren't on any queues. | * aren't on any queues. | ||||
| */ | */ | ||||
| if (m == NULL) { | if (m == NULL) { | ||||
| if ((flags & M_NOWAIT) == 0) | if ((flags & M_NOWAIT) == 0) { | ||||
| pctrie_iter_reset(&pages); | |||||
| goto retry; | goto retry; | ||||
| } | |||||
| VM_OBJECT_WUNLOCK(object); | VM_OBJECT_WUNLOCK(object); | ||||
| kmem_unback(object, addr, i); | kmem_unback(object, addr, i); | ||||
| return (KERN_NO_SPACE); | return (KERN_NO_SPACE); | ||||
| } | } | ||||
| KASSERT(vm_page_domain(m) == domain, | KASSERT(vm_page_domain(m) == domain, | ||||
| ("kmem_back_domain: Domain mismatch %d != %d", | ("kmem_back_domain: Domain mismatch %d != %d", | ||||
| vm_page_domain(m), domain)); | vm_page_domain(m), domain)); | ||||
| if (flags & M_ZERO && (m->flags & PG_ZERO) == 0) | if (flags & M_ZERO && (m->flags & PG_ZERO) == 0) | ||||
| ▲ Show 20 Lines • Show All 485 Lines • Show Last 20 Lines | |||||