Author: kib
Date: Thu Jul 26 09:06:48 2012
New Revision: 238791
URL: http://svn.freebsd.org/changeset/base/238791

Log:
  Do not requeue held page or page for which locking failed, just leave
  them alone.
  
  Process the act_count updates for the held pages in the vm_pageout
  loop over the inactive queue, instead of refusing to do anything with
  such page.
  
  Clarify the intent of the addl_page_shortage counter and change its
  use for pages which are not processed in the loop according to the
  description.
  
  Reviewed by:  alc
  MFC after:    2 weeks

Modified:
  head/sys/vm/vm_pageout.c

Modified: head/sys/vm/vm_pageout.c
==============================================================================
--- head/sys/vm/vm_pageout.c    Thu Jul 26 08:10:29 2012        (r238790)
+++ head/sys/vm/vm_pageout.c    Thu Jul 26 09:06:48 2012        (r238791)
@@ -889,6 +889,12 @@ vm_pageout_scan(int pass)
         */
        uma_reclaim();
 
+       /*
+        * The addl_page_shortage is the the number of temporarily
+        * stuck pages in the inactive queue.  In other words, the
+        * number of pages from cnt.v_inactive_count that should be
+        * discounted in setting the target for the active queue scan.
+        */
        addl_page_shortage = atomic_readandclear_int(&vm_pageout_deficit);
 
        /*
@@ -945,38 +951,31 @@ vm_pageout_scan(int pass)
                    ("Unmanaged page %p cannot be in inactive queue", m));
 
                /*
-                * Lock the page.
+                * The page or object lock acquisitions fail if the
+                * page was removed from the queue or moved to a
+                * different position within the queue.  In either
+                * case, addl_page_shortage should not be incremented.
                 */
                if (!vm_pageout_page_lock(m, &next)) {
                        vm_page_unlock(m);
-                       addl_page_shortage++;
                        continue;
                }
-
-               /*
-                * A held page may be undergoing I/O, so skip it.
-                */
-               if (m->hold_count) {
+               object = m->object;
+               if (!VM_OBJECT_TRYLOCK(object) &&
+                   !vm_pageout_fallback_object_lock(m, &next)) {
                        vm_page_unlock(m);
-                       vm_page_requeue(m);
-                       addl_page_shortage++;
+                       VM_OBJECT_UNLOCK(object);
                        continue;
                }
 
                /*
-                * Don't mess with busy pages, keep in the front of the
-                * queue, most likely are being paged out.
+                * Don't mess with busy pages, keep them at at the
+                * front of the queue, most likely they are being
+                * paged out.  Increment addl_page_shortage for busy
+                * pages, because they may leave the inactive queue
+                * shortly after page scan is finished.
                 */
-               object = m->object;
-               if (!VM_OBJECT_TRYLOCK(object) &&
-                   (!vm_pageout_fallback_object_lock(m, &next) ||
-                   m->hold_count != 0)) {
-                       VM_OBJECT_UNLOCK(object);
-                       vm_page_unlock(m);
-                       addl_page_shortage++;
-                       continue;
-               }
-               if (m->busy || (m->oflags & VPO_BUSY)) {
+               if (m->busy != 0 || (m->oflags & VPO_BUSY) != 0) {
                        vm_page_unlock(m);
                        VM_OBJECT_UNLOCK(object);
                        addl_page_shortage++;
@@ -1036,6 +1035,21 @@ vm_pageout_scan(int pass)
                        goto relock_queues;
                }
 
+               if (m->hold_count != 0) {
+                       vm_page_unlock(m);
+                       VM_OBJECT_UNLOCK(object);
+
+                       /*
+                        * Held pages are essentially stuck in the
+                        * queue.  So, they ought to be discounted
+                        * from cnt.v_inactive_count.  See the
+                        * calculation of the page_shortage for the
+                        * loop over the active queue below.
+                        */
+                       addl_page_shortage++;
+                       goto relock_queues;
+               }
+
                /*
                 * If the upper level VM system does not believe that the page
                 * is fully dirty, but it is mapped for write access, then we
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to