Index: sys/vm/vm_phys.c =================================================================== --- sys/vm/vm_phys.c +++ sys/vm/vm_phys.c @@ -1103,6 +1103,7 @@ struct vm_phys_seg *seg; vm_paddr_t pa; vm_page_t m_buddy; + int ord_cap; KASSERT(m->order == VM_NFREEORDER, ("vm_phys_free_pages: page %p has unexpected order %d", @@ -1116,10 +1117,11 @@ vm_domain_free_assert_locked(VM_DOMAIN(seg->domain)); if (order < VM_NFREEORDER - 1) { pa = VM_PAGE_TO_PHYS(m); - do { + ord_cap = VM_NFREEORDER; + ord_cap = min(ord_cap, fls((pa & -seg->start) >> PAGE_SHIFT)); + ord_cap = min(ord_cap, fls((~pa & seg->end) >> PAGE_SHIFT)); + while (order < ord_cap - 1) { pa ^= ((vm_paddr_t)1 << (PAGE_SHIFT + order)); - if (pa < seg->start || pa >= seg->end) - break; m_buddy = &seg->first_page[atop(pa - seg->start)]; if (m_buddy->order != order) break; @@ -1130,7 +1132,7 @@ order++; pa &= ~(((vm_paddr_t)1 << (PAGE_SHIFT + order)) - 1); m = &seg->first_page[atop(pa - seg->start)]; - } while (order < VM_NFREEORDER - 1); + } } fl = (*seg->free_queues)[m->pool]; vm_freelist_add(fl, m, order, 1);