diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -2972,17 +2972,29 @@
 	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"));
 	KASSERT(powerof2(alignment), ("alignment is not a power of 2"));
 	KASSERT(powerof2(boundary), ("boundary is not a power of 2"));
-	req_class = req & VM_ALLOC_CLASS_MASK;
+
+	/*
+	 * The caller will attempt an allocation after some runs have been
+	 * reclaimed and added to the vm_phys buddy lists.  Due to limitations
+	 * of vm_phys_alloc_contig(), round up the requested length to the next
+	 * power of 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);
 
 	/*
 	 * The page daemon is allowed to dig deeper into the free page list.
 	 */
+	req_class = req & VM_ALLOC_CLASS_MASK;
 	if (curproc == pageproc && req_class != VM_ALLOC_INTERRUPT)
 		req_class = VM_ALLOC_SYSTEM;