svn commit: r272543 - stable/10/sys/vm

Alan Cox alc at FreeBSD.org
Sat Oct 4 22:52:22 UTC 2014


Author: alc
Date: Sat Oct  4 22:52:21 2014
New Revision: 272543
URL: https://svnweb.freebsd.org/changeset/base/272543

Log:
  MFC r271351
    Fix a boundary case error in vm_reserv_alloc_contig().

Modified:
  stable/10/sys/vm/vm_reserv.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/vm/vm_reserv.c
==============================================================================
--- stable/10/sys/vm/vm_reserv.c	Sat Oct  4 20:35:07 2014	(r272542)
+++ stable/10/sys/vm/vm_reserv.c	Sat Oct  4 22:52:21 2014	(r272543)
@@ -299,7 +299,7 @@ vm_reserv_populate(vm_reserv_t rv)
 
 /*
  * Allocates a contiguous set of physical pages of the given size "npages"
- * from an existing or newly-created reservation.  All of the physical pages
+ * from existing or newly created reservations.  All of the physical pages
  * must be at or above the given physical address "low" and below the given
  * physical address "high".  The given value "alignment" determines the
  * alignment of the first physical page in the set.  If the given value
@@ -371,8 +371,8 @@ vm_reserv_alloc_contig(vm_object_t objec
 
 	/*
 	 * Could at least one reservation fit between the first index to the
-	 * left that can be used and the first index to the right that cannot
-	 * be used?
+	 * left that can be used ("leftcap") and the first index to the right
+	 * that cannot be used ("rightcap")?
 	 */
 	first = pindex - VM_RESERV_INDEX(object, pindex);
 	if (mpred != NULL) {
@@ -394,6 +394,13 @@ vm_reserv_alloc_contig(vm_object_t objec
 		if (first + maxpages > rightcap) {
 			if (maxpages == VM_LEVEL_0_NPAGES)
 				return (NULL);
+
+			/*
+			 * At least one reservation will fit between "leftcap"
+			 * and "rightcap".  However, a reservation for the
+			 * last of the requested pages will not fit.  Reduce
+			 * the size of the upcoming allocation accordingly.
+			 */
 			allocpages = minpages;
 		}
 	}
@@ -417,16 +424,23 @@ vm_reserv_alloc_contig(vm_object_t objec
 	}
 
 	/*
-	 * Allocate and populate the new reservations.  The alignment and
-	 * boundary specified for this allocation may be different from the
-	 * alignment and boundary specified for the requested pages.  For
-	 * instance, the specified index may not be the first page within the
-	 * first new reservation.
+	 * Allocate the physical pages.  The alignment and boundary specified
+	 * for this allocation may be different from the alignment and
+	 * boundary specified for the requested pages.  For instance, the
+	 * specified index may not be the first page within the first new
+	 * reservation.
 	 */
 	m = vm_phys_alloc_contig(allocpages, low, high, ulmax(alignment,
 	    VM_LEVEL_0_SIZE), boundary > VM_LEVEL_0_SIZE ? boundary : 0);
 	if (m == NULL)
 		return (NULL);
+
+	/*
+	 * The allocated physical pages always begin at a reservation
+	 * boundary, but they do not always end at a reservation boundary.
+	 * Initialize every reservation that is completely covered by the
+	 * allocated physical pages.
+	 */
 	m_ret = NULL;
 	index = VM_RESERV_INDEX(object, pindex);
 	do {
@@ -456,7 +470,7 @@ vm_reserv_alloc_contig(vm_object_t objec
 		m += VM_LEVEL_0_NPAGES;
 		first += VM_LEVEL_0_NPAGES;
 		allocpages -= VM_LEVEL_0_NPAGES;
-	} while (allocpages > 0);
+	} while (allocpages >= VM_LEVEL_0_NPAGES);
 	return (m_ret);
 
 	/*


More information about the svn-src-all mailing list