Index: sys/vm/vm_page.c =================================================================== --- sys/vm/vm_page.c +++ sys/vm/vm_page.c @@ -1996,10 +1996,8 @@ } /* - * Allocate a page in the specified object with the given page index. To - * optimize insertion of the page into the object, the caller must also specify - * the resident page in the object with largest index smaller than the given - * page index, or NULL if no such page exists. + * Allocate a page in the specified object with the given page index. If the + * object lock is dropped and regained, the pages iter is reset. */ vm_page_t vm_page_alloc_iter(vm_object_t object, vm_pindex_t pindex, int req, @@ -2141,9 +2139,9 @@ /* * Not allocatable, give up. */ - pctrie_iter_reset(pages); - if (vm_domain_alloc_fail(vmd, object, req)) - goto again; + vm_domain_alloc_fail(vmd, object, req); + if (req & VM_ALLOC_WAITFAIL) + pctrie_iter_reset(pages); return (NULL); } @@ -2335,26 +2333,23 @@ KASSERT(npages > 0, ("vm_page_alloc_contig: npages is zero")); vm_page_iter_init(&pages, object); - mpred = vm_radix_iter_lookup_lt(&pages, pindex); - KASSERT(mpred == NULL || mpred->pindex != pindex, - ("vm_page_alloc_contig: pindex already allocated")); - for (;;) { + m_ret = NULL; #if VM_NRESERVLEVEL > 0 - /* - * Can we allocate the pages from a reservation? - */ - if (vm_object_reserv(object) && - (m_ret = vm_reserv_alloc_contig(object, pindex, domain, - req, npages, low, high, alignment, boundary, &pages)) != - NULL) { - break; - } + /* + * Can we allocate the pages from a reservation? + */ + if (vm_object_reserv(object)) { + m_ret = vm_reserv_alloc_contig(object, pindex, domain, + req, npages, low, high, alignment, boundary, &pages); + } #endif - if ((m_ret = vm_page_find_contig_domain(domain, req, npages, - low, high, alignment, boundary)) != NULL) - break; - if (!vm_domain_alloc_fail(VM_DOMAIN(domain), object, req)) - return (NULL); + if (m_ret == NULL) { + m_ret = vm_page_find_contig_domain(domain, req, npages, + low, high, alignment, boundary); + } + if (m_ret == NULL) { + (void)vm_domain_alloc_fail(VM_DOMAIN(domain), object, req); + return (NULL); } /* @@ -2408,7 +2403,6 @@ } return (NULL); } - mpred = m; if (memattr != VM_MEMATTR_DEFAULT) pmap_page_set_memattr(m, memattr); pindex++; @@ -2467,9 +2461,9 @@ } } if (m == NULL) { - if (vm_domain_alloc_fail(vmd, NULL, req)) - goto again; - return (NULL); + if (!vm_domain_alloc_fail(vmd, NULL, req)) + return (NULL); + goto again; } found: @@ -5189,6 +5183,7 @@ break; m = vm_page_alloc_iter(object, pindex + i, pflags | VM_ALLOC_COUNT(count - i), &pages); + /* pages was reset if alloc_iter lost the lock. */ if (m == NULL) { if ((allocflags & (VM_ALLOC_NOWAIT | VM_ALLOC_WAITFAIL)) != 0)