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);
 
        /*
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to