Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Sep 2014 05:52:30 +0000 (UTC)
From:      Alan Cox <alc@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r271351 - head/sys/vm
Message-ID:  <201409100552.s8A5qUjC039448@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: alc
Date: Wed Sep 10 05:52:30 2014
New Revision: 271351
URL: http://svnweb.freebsd.org/changeset/base/271351

Log:
  Fix a boundary case error in vm_reserv_alloc_contig(): If a reservation
  isn't being allocated for the last of the requested pages, because a
  reservation won't fit in the gap between allocated pages, then the
  reservation structure shouldn't be initialized.
  
  While I'm here, improve the nearby comments.
  
  Reported by:	jeff, pho
  MFC after:	1 week
  Sponsored by:	EMC / Isilon Storage Division

Modified:
  head/sys/vm/vm_reserv.c

Modified: head/sys/vm/vm_reserv.c
==============================================================================
--- head/sys/vm/vm_reserv.c	Wed Sep 10 05:44:15 2014	(r271350)
+++ head/sys/vm/vm_reserv.c	Wed Sep 10 05:52:30 2014	(r271351)
@@ -364,7 +364,7 @@ vm_reserv_populate(vm_reserv_t rv, int i
 
 /*
  * 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
@@ -436,8 +436,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) {
@@ -459,6 +459,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;
 		}
 	}
@@ -482,16 +489,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 {
@@ -525,7 +539,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);
 
 	/*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409100552.s8A5qUjC039448>