Index: sys/vm/vm_page.c =================================================================== --- sys/vm/vm_page.c +++ sys/vm/vm_page.c @@ -2972,7 +2972,7 @@ struct vm_domain *vmd; vm_paddr_t curr_low; vm_page_t m_run, m_runs[NRUNS]; - u_long count, reclaimed; + u_long count, minalign, reclaimed; int error, i, options, req_class; KASSERT(npages > 0, ("npages is 0")); @@ -2997,6 +2997,18 @@ (count < npages && req_class == VM_ALLOC_INTERRUPT)) return (false); + /* + * The caller will attempt an allocation after some runs have been + * reclaimed and added to the vm_phys buddy lists. To ensure that runs + * are not fragmented, round up the requested length to the next power + * or two or maximum chunk size, and ensure that each run is suitably + * aligned. + */ + minalign = 1ul << imin(flsl(npages - 1), VM_NFREEORDER - 1); + npages = roundup2(npages, minalign); + if (alignment < ptoa(minalign)) + alignment = ptoa(minalign); + /* * Scan up to three times, relaxing the restrictions ("options") on * the reclamation of reservations and superpages each time.