Date: Wed, 5 Sep 2012 18:55:35 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r240149 - stable/9/sys/vm Message-ID: <201209051855.q85ItZYB085676@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Wed Sep 5 18:55:35 2012 New Revision: 240149 URL: http://svn.freebsd.org/changeset/base/240149 Log: MFC r238791: 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. Modified: stable/9/sys/vm/vm_pageout.c Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/vm/vm_pageout.c ============================================================================== --- stable/9/sys/vm/vm_pageout.c Wed Sep 5 18:52:01 2012 (r240148) +++ stable/9/sys/vm/vm_pageout.c Wed Sep 5 18:55:35 2012 (r240149) @@ -754,6 +754,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); /* @@ -810,38 +816,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++; @@ -901,6 +900,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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201209051855.q85ItZYB085676>