Author: alc
Date: Sun May  2 17:33:46 2010
New Revision: 207530
URL: http://svn.freebsd.org/changeset/base/207530

Log:
  It makes no sense for vm_page_sleep_if_busy()'s helper, vm_page_sleep(),
  to unconditionally set PG_REFERENCED on a page before sleeping.  In many
  cases, it's perfectly ok for the page to disappear, i.e., be reclaimed by
  the page daemon, before the caller to vm_page_sleep() is reawakened.
  Instead, we now explicitly set PG_REFERENCED in those cases where having
  the page persist until the caller is awakened is clearly desirable.  Note,
  however, that setting PG_REFERENCED on the page is still only a hint,
  and not a guarantee that the page should persist.

Modified:
  head/sys/fs/tmpfs/tmpfs_vnops.c
  head/sys/kern/vfs_bio.c
  head/sys/vm/vm_fault.c
  head/sys/vm/vm_page.c

Modified: head/sys/fs/tmpfs/tmpfs_vnops.c
==============================================================================
--- head/sys/fs/tmpfs/tmpfs_vnops.c     Sun May  2 16:55:13 2010        
(r207529)
+++ head/sys/fs/tmpfs/tmpfs_vnops.c     Sun May  2 17:33:46 2010        
(r207530)
@@ -516,8 +516,16 @@ tmpfs_mappedread(vm_object_t vobj, vm_ob
 lookupvpg:
        if (((m = vm_page_lookup(vobj, idx)) != NULL) &&
            vm_page_is_valid(m, offset, tlen)) {
-               if (vm_page_sleep_if_busy(m, FALSE, "tmfsmr"))
+               if ((m->oflags & VPO_BUSY) != 0) {
+                       /*
+                        * Reference the page before unlocking and sleeping so
+                        * that the page daemon is less likely to reclaim it.  
+                        */
+                       vm_page_lock_queues();
+                       vm_page_flag_set(m, PG_REFERENCED);
+                       vm_page_sleep(m, "tmfsmr");
                        goto lookupvpg;
+               }
                vm_page_busy(m);
                VM_OBJECT_UNLOCK(vobj);
                error = uiomove_fromphys(&m, offset, tlen, uio);
@@ -526,8 +534,16 @@ lookupvpg:
                VM_OBJECT_UNLOCK(vobj);
                return  (error);
        } else if (m != NULL && uio->uio_segflg == UIO_NOCOPY) {
-               if (vm_page_sleep_if_busy(m, FALSE, "tmfsmr"))
+               if ((m->oflags & VPO_BUSY) != 0) {
+                       /*
+                        * Reference the page before unlocking and sleeping so
+                        * that the page daemon is less likely to reclaim it.  
+                        */
+                       vm_page_lock_queues();
+                       vm_page_flag_set(m, PG_REFERENCED);
+                       vm_page_sleep(m, "tmfsmr");
                        goto lookupvpg;
+               }
                vm_page_busy(m);
                VM_OBJECT_UNLOCK(vobj);
                sched_pin();
@@ -627,8 +643,16 @@ tmpfs_mappedwrite(vm_object_t vobj, vm_o
 lookupvpg:
        if (((vpg = vm_page_lookup(vobj, idx)) != NULL) &&
            vm_page_is_valid(vpg, offset, tlen)) {
-               if (vm_page_sleep_if_busy(vpg, FALSE, "tmfsmw"))
+               if ((vpg->oflags & VPO_BUSY) != 0) {
+                       /*
+                        * Reference the page before unlocking and sleeping so
+                        * that the page daemon is less likely to reclaim it.  
+                        */
+                       vm_page_lock_queues();
+                       vm_page_flag_set(vpg, PG_REFERENCED);
+                       vm_page_sleep(vpg, "tmfsmw");
                        goto lookupvpg;
+               }
                vm_page_busy(vpg);
                vm_page_lock_queues();
                vm_page_undirty(vpg);

Modified: head/sys/kern/vfs_bio.c
==============================================================================
--- head/sys/kern/vfs_bio.c     Sun May  2 16:55:13 2010        (r207529)
+++ head/sys/kern/vfs_bio.c     Sun May  2 17:33:46 2010        (r207530)
@@ -3024,8 +3024,17 @@ allocbuf(struct buf *bp, int size)
                                 *  vm_fault->getpages->cluster_read->allocbuf
                                 *
                                 */
-                               if (vm_page_sleep_if_busy(m, FALSE, "pgtblk"))
+                               if ((m->oflags & VPO_BUSY) != 0) {
+                                       /*
+                                        * Reference the page before unlocking
+                                        * and sleeping so that the page daemon
+                                        * is less likely to reclaim it.  
+                                        */
+                                       vm_page_lock_queues();
+                                       vm_page_flag_set(m, PG_REFERENCED);
+                                       vm_page_sleep(m, "pgtblk");
                                        continue;
+                               }
 
                                /*
                                 * We have a good page.

Modified: head/sys/vm/vm_fault.c
==============================================================================
--- head/sys/vm/vm_fault.c      Sun May  2 16:55:13 2010        (r207529)
+++ head/sys/vm/vm_fault.c      Sun May  2 17:33:46 2010        (r207530)
@@ -338,6 +338,12 @@ RetryFault:;
                         * to pmap it.
                         */
                        if ((fs.m->oflags & VPO_BUSY) || fs.m->busy) {
+                               /*
+                                * Reference the page before unlocking and
+                                * sleeping so that the page daemon is less
+                                * likely to reclaim it. 
+                                */
+                               vm_page_flag_set(fs.m, PG_REFERENCED);
                                vm_page_unlock_queues();
                                vm_page_unlock(fs.m);
                                VM_OBJECT_UNLOCK(fs.object);

Modified: head/sys/vm/vm_page.c
==============================================================================
--- head/sys/vm/vm_page.c       Sun May  2 16:55:13 2010        (r207529)
+++ head/sys/vm/vm_page.c       Sun May  2 17:33:46 2010        (r207530)
@@ -599,7 +599,7 @@ vm_page_free_zero(vm_page_t m)
 /*
  *     vm_page_sleep:
  *
- *     Sleep and release the page queues lock.
+ *     Sleep and release the page and page queues locks.
  *
  *     The object containing the given page must be locked.
  */
@@ -608,13 +608,10 @@ vm_page_sleep(vm_page_t m, const char *m
 {
 
        VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED);
-       if (!mtx_owned(vm_page_lockptr(m)))
-               vm_page_lock(m);
-       if (!mtx_owned(&vm_page_queue_mtx))
-               vm_page_lock_queues();
-       vm_page_flag_set(m, PG_REFERENCED);
-       vm_page_unlock_queues();
-       vm_page_unlock(m);
+       if (mtx_owned(&vm_page_queue_mtx))
+               vm_page_unlock_queues();
+       if (mtx_owned(vm_page_lockptr(m)))
+               vm_page_unlock(m);
 
        /*
         * It's possible that while we sleep, the page will get
@@ -1896,7 +1893,17 @@ vm_page_grab(vm_object_t object, vm_pind
        VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
 retrylookup:
        if ((m = vm_page_lookup(object, pindex)) != NULL) {
-               if (vm_page_sleep_if_busy(m, TRUE, "pgrbwt")) {
+               if ((m->oflags & VPO_BUSY) != 0 || m->busy != 0) {
+                       if ((allocflags & VM_ALLOC_RETRY) != 0) {
+                               /*
+                                * Reference the page before unlocking and
+                                * sleeping so that the page daemon is less
+                                * likely to reclaim it. 
+                                */
+                               vm_page_lock_queues();
+                               vm_page_flag_set(m, PG_REFERENCED);
+                       }
+                       vm_page_sleep(m, "pgrbwt");
                        if ((allocflags & VM_ALLOC_RETRY) == 0)
                                return (NULL);
                        goto retrylookup;
_______________________________________________
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