Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/vm_page.c
Show First 20 Lines • Show All 2,172 Lines • ▼ Show 20 Lines | m = vm_page_alloc_contig_domain(object, pindex, domain, req, | ||||
npages, low, high, alignment, boundary, memattr); | npages, low, high, alignment, boundary, memattr); | ||||
if (m != NULL) | if (m != NULL) | ||||
break; | break; | ||||
} while (vm_domainset_iter_page(&di, object, &domain) == 0); | } while (vm_domainset_iter_page(&di, object, &domain) == 0); | ||||
return (m); | return (m); | ||||
} | } | ||||
static vm_page_t | |||||
vm_page_find_contig_domain(int domain, int req, u_long npages, vm_paddr_t low, | |||||
vm_paddr_t high, u_long alignment, vm_paddr_t boundary) | |||||
{ | |||||
struct vm_domain *vmd; | |||||
vm_page_t m_ret; | |||||
vmd = VM_DOMAIN(domain); | |||||
if (!vm_domain_allocate(vmd, req, npages)) | |||||
return (NULL); | |||||
#if VM_NRESERVLEVEL > 0 | |||||
again: | |||||
#endif | |||||
/* | |||||
* Try to allocate the pages from the free page queues. | |||||
kib: This partial sentence should be reformulated now, I believe. Out of old context it is not… | |||||
*/ | |||||
vm_domain_free_lock(vmd); | |||||
m_ret = vm_phys_alloc_contig(domain, npages, low, high, | |||||
alignment, boundary); | |||||
vm_domain_free_unlock(vmd); | |||||
if (m_ret != NULL) | |||||
return (m_ret); | |||||
vm_domain_freecnt_inc(vmd, npages); | |||||
#if VM_NRESERVLEVEL > 0 | |||||
/* | |||||
* Try to break a reservation to replenish free page queues | |||||
* in a way that allows the allocation to succeed. | |||||
*/ | |||||
Done Inline ActionsNow in vm_page_alloc_contig_domain(), this would loop without retrying vm_reserv_alloc_contig(). Was it intended? From the commit message it seems so, but vm_domain_alloc_fail() drops object lock which might change the disposition for reservations? kib: Now in vm_page_alloc_contig_domain(), this would loop without retrying vm_reserv_alloc_contig(). | |||||
Done Inline ActionsIt was intended. Now, if vm_reserv_reclaim_contig returns true, control goes to vm_reserv_object && vm_reserv_alloc_contig without a call to vm_domain_alloc_fail, so the object lock would not have been dropped, and the vm_reserv_alloc_contig call will fail a second time. dougm: It was intended. Now, if vm_reserv_reclaim_contig returns true, control goes to… | |||||
if ((req & VM_ALLOC_NORECLAIM) == 0 && | |||||
vm_reserv_reclaim_contig(domain, npages, low, | |||||
high, alignment, boundary)) | |||||
goto again; | |||||
#endif | |||||
return (m_ret); | |||||
} | |||||
vm_page_t | vm_page_t | ||||
vm_page_alloc_contig_domain(vm_object_t object, vm_pindex_t pindex, int domain, | vm_page_alloc_contig_domain(vm_object_t object, vm_pindex_t pindex, int domain, | ||||
int req, u_long npages, vm_paddr_t low, vm_paddr_t high, u_long alignment, | int req, u_long npages, vm_paddr_t low, vm_paddr_t high, u_long alignment, | ||||
vm_paddr_t boundary, vm_memattr_t memattr) | vm_paddr_t boundary, vm_memattr_t memattr) | ||||
{ | { | ||||
struct vm_domain *vmd; | |||||
vm_page_t m, m_ret, mpred; | vm_page_t m, m_ret, mpred; | ||||
u_int busy_lock, flags, oflags; | u_int busy_lock, flags, oflags; | ||||
#define VPAC_FLAGS (VPA_FLAGS | VM_ALLOC_NORECLAIM) | #define VPAC_FLAGS (VPA_FLAGS | VM_ALLOC_NORECLAIM) | ||||
KASSERT((req & ~VPAC_FLAGS) == 0, | KASSERT((req & ~VPAC_FLAGS) == 0, | ||||
("invalid request %#x", req)); | ("invalid request %#x", req)); | ||||
KASSERT(((req & (VM_ALLOC_NOBUSY | VM_ALLOC_SBUSY)) != | KASSERT(((req & (VM_ALLOC_NOBUSY | VM_ALLOC_SBUSY)) != | ||||
(VM_ALLOC_NOBUSY | VM_ALLOC_SBUSY)), | (VM_ALLOC_NOBUSY | VM_ALLOC_SBUSY)), | ||||
Show All 10 Lines | #define VPAC_FLAGS (VPA_FLAGS | VM_ALLOC_NORECLAIM) | ||||
mpred = vm_radix_lookup_le(&object->rtree, pindex); | mpred = vm_radix_lookup_le(&object->rtree, pindex); | ||||
KASSERT(mpred == NULL || mpred->pindex != pindex, | KASSERT(mpred == NULL || mpred->pindex != pindex, | ||||
("vm_page_alloc_contig: pindex already allocated")); | ("vm_page_alloc_contig: pindex already allocated")); | ||||
/* | /* | ||||
* Can we allocate the pages without the number of free pages falling | * Can we allocate the pages without the number of free pages falling | ||||
* below the lower bound for the allocation class? | * below the lower bound for the allocation class? | ||||
*/ | */ | ||||
m_ret = NULL; | for (;;) { | ||||
again: | |||||
#if VM_NRESERVLEVEL > 0 | #if VM_NRESERVLEVEL > 0 | ||||
/* | /* | ||||
* Can we allocate the pages from a reservation? | * Can we allocate the pages from a reservation? | ||||
*/ | */ | ||||
if (vm_object_reserv(object) && | if (vm_object_reserv(object) && | ||||
(m_ret = vm_reserv_alloc_contig(object, pindex, domain, req, | (m_ret = vm_reserv_alloc_contig(object, pindex, domain, req, | ||||
mpred, npages, low, high, alignment, boundary)) != NULL) { | mpred, npages, low, high, alignment, boundary)) != NULL) { | ||||
goto found; | break; | ||||
} | } | ||||
#endif | #endif | ||||
vmd = VM_DOMAIN(domain); | if ((m_ret = vm_page_find_contig_domain(domain, req, npages, | ||||
if (vm_domain_allocate(vmd, req, npages)) { | low, high, alignment, boundary)) != NULL) | ||||
/* | break; | ||||
* allocate them from the free page queues. | if (!vm_domain_alloc_fail(VM_DOMAIN(domain), object, req)) | ||||
*/ | |||||
vm_domain_free_lock(vmd); | |||||
m_ret = vm_phys_alloc_contig(domain, npages, low, high, | |||||
alignment, boundary); | |||||
vm_domain_free_unlock(vmd); | |||||
if (m_ret == NULL) { | |||||
vm_domain_freecnt_inc(vmd, npages); | |||||
#if VM_NRESERVLEVEL > 0 | |||||
if ((req & VM_ALLOC_NORECLAIM) == 0 && | |||||
vm_reserv_reclaim_contig(domain, npages, low, | |||||
high, alignment, boundary)) | |||||
goto again; | |||||
#endif | |||||
} | |||||
} | |||||
if (m_ret == NULL) { | |||||
if (vm_domain_alloc_fail(vmd, object, req)) | |||||
goto again; | |||||
return (NULL); | return (NULL); | ||||
} | } | ||||
#if VM_NRESERVLEVEL > 0 | |||||
found: | |||||
#endif | |||||
for (m = m_ret; m < &m_ret[npages]; m++) { | for (m = m_ret; m < &m_ret[npages]; m++) { | ||||
vm_page_dequeue(m); | vm_page_dequeue(m); | ||||
vm_page_alloc_check(m); | vm_page_alloc_check(m); | ||||
} | } | ||||
/* | /* | ||||
* Initialize the pages. Only the PG_ZERO flag is inherited. | * Initialize the pages. Only the PG_ZERO flag is inherited. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 197 Lines • ▼ Show 20 Lines | vm_page_alloc_noobj_contig(int req, u_long npages, vm_paddr_t low, | ||||
return (m); | return (m); | ||||
} | } | ||||
vm_page_t | vm_page_t | ||||
vm_page_alloc_noobj_contig_domain(int domain, int req, u_long npages, | vm_page_alloc_noobj_contig_domain(int domain, int req, u_long npages, | ||||
vm_paddr_t low, vm_paddr_t high, u_long alignment, vm_paddr_t boundary, | vm_paddr_t low, vm_paddr_t high, u_long alignment, vm_paddr_t boundary, | ||||
vm_memattr_t memattr) | vm_memattr_t memattr) | ||||
{ | { | ||||
struct vm_domain *vmd; | |||||
vm_page_t m, m_ret; | vm_page_t m, m_ret; | ||||
u_int flags; | u_int flags; | ||||
#define VPANC_FLAGS (VPAN_FLAGS | VM_ALLOC_NORECLAIM) | #define VPANC_FLAGS (VPAN_FLAGS | VM_ALLOC_NORECLAIM) | ||||
KASSERT((req & ~VPANC_FLAGS) == 0, | KASSERT((req & ~VPANC_FLAGS) == 0, | ||||
("invalid request %#x", req)); | ("invalid request %#x", req)); | ||||
KASSERT((req & (VM_ALLOC_WAITOK | VM_ALLOC_NORECLAIM)) != | KASSERT((req & (VM_ALLOC_WAITOK | VM_ALLOC_NORECLAIM)) != | ||||
(VM_ALLOC_WAITOK | VM_ALLOC_NORECLAIM), | (VM_ALLOC_WAITOK | VM_ALLOC_NORECLAIM), | ||||
("invalid request %#x", req)); | ("invalid request %#x", req)); | ||||
KASSERT(((req & (VM_ALLOC_NOBUSY | VM_ALLOC_SBUSY)) != | KASSERT(((req & (VM_ALLOC_NOBUSY | VM_ALLOC_SBUSY)) != | ||||
(VM_ALLOC_NOBUSY | VM_ALLOC_SBUSY)), | (VM_ALLOC_NOBUSY | VM_ALLOC_SBUSY)), | ||||
("invalid request %#x", req)); | ("invalid request %#x", req)); | ||||
KASSERT(npages > 0, ("vm_page_alloc_contig: npages is zero")); | KASSERT(npages > 0, ("vm_page_alloc_contig: npages is zero")); | ||||
m_ret = NULL; | while ((m_ret = vm_page_find_contig_domain(domain, req, npages, | ||||
again: | low, high, alignment, boundary)) == NULL) { | ||||
vmd = VM_DOMAIN(domain); | if (!vm_domain_alloc_fail(VM_DOMAIN(domain), NULL, req)) | ||||
if (vm_domain_allocate(vmd, req, npages)) { | |||||
/* | |||||
* allocate them from the free page queues. | |||||
*/ | |||||
vm_domain_free_lock(vmd); | |||||
m_ret = vm_phys_alloc_contig(domain, npages, low, high, | |||||
alignment, boundary); | |||||
vm_domain_free_unlock(vmd); | |||||
if (m_ret == NULL) { | |||||
vm_domain_freecnt_inc(vmd, npages); | |||||
#if VM_NRESERVLEVEL > 0 | |||||
if ((req & VM_ALLOC_NORECLAIM) == 0 && | |||||
vm_reserv_reclaim_contig(domain, npages, low, | |||||
high, alignment, boundary)) | |||||
goto again; | |||||
#endif | |||||
} | |||||
} | |||||
if (m_ret == NULL) { | |||||
if (vm_domain_alloc_fail(vmd, NULL, req)) | |||||
goto again; | |||||
return (NULL); | return (NULL); | ||||
} | } | ||||
/* | /* | ||||
* Initialize the pages. Only the PG_ZERO flag is inherited. | * Initialize the pages. Only the PG_ZERO flag is inherited. | ||||
*/ | */ | ||||
flags = PG_ZERO; | flags = PG_ZERO; | ||||
if ((req & VM_ALLOC_NODUMP) != 0) | if ((req & VM_ALLOC_NODUMP) != 0) | ||||
flags |= PG_NODUMP; | flags |= PG_NODUMP; | ||||
▲ Show 20 Lines • Show All 3,096 Lines • Show Last 20 Lines |
This partial sentence should be reformulated now, I believe. Out of old context it is not sufficient, and should be a normal sentence.