Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/rump/librump Shuffle the pagedaemon algorithm a bit to r...



details:   https://anonhg.NetBSD.org/src/rev/6ba381257532
branches:  trunk
changeset: 762542:6ba381257532
user:      pooka <pooka%NetBSD.org@localhost>
date:      Tue Feb 22 20:17:37 2011 +0000

description:
Shuffle the pagedaemon algorithm a bit to record the number of
pageouts active and give up only if the pagedaemon could not free
memory and there are no outstanding pageouts.

This should fix the "out of memory" pauses reported by Mihai Chelaru
and Taylor R Campbell.  Tested by copying files to and from an ffs
backed by /dev/wd0 (with and without -o log) using a 1MB rump kernel
memory limit.

diffstat:

 sys/rump/librump/rumpkern/vm.c    |  59 ++++++++++++++++++++++----------------
 sys/rump/librump/rumpvfs/vm_vfs.c |   7 ++-
 2 files changed, 38 insertions(+), 28 deletions(-)

diffs (173 lines):

diff -r 10b9082c0342 -r 6ba381257532 sys/rump/librump/rumpkern/vm.c
--- a/sys/rump/librump/rumpkern/vm.c    Tue Feb 22 18:45:10 2011 +0000
+++ b/sys/rump/librump/rumpkern/vm.c    Tue Feb 22 20:17:37 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vm.c,v 1.112 2011/02/22 18:43:20 pooka Exp $   */
+/*     $NetBSD: vm.c,v 1.113 2011/02/22 20:17:38 pooka Exp $   */
 
 /*
  * Copyright (c) 2007-2010 Antti Kantee.  All Rights Reserved.
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.112 2011/02/22 18:43:20 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.113 2011/02/22 20:17:38 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -923,14 +923,27 @@
 uvm_pageout_start(int npages)
 {
 
-       /* we don't have the heuristics */
+       mutex_enter(&pdaemonmtx);
+       uvmexp.paging += npages;
+       mutex_exit(&pdaemonmtx);
 }
 
 void
 uvm_pageout_done(int npages)
 {
 
-       /* could wakeup waiters, but just let the pagedaemon do it */
+       if (!npages)
+               return;
+
+       mutex_enter(&pdaemonmtx);
+       KASSERT(uvmexp.paging >= npages);
+       uvmexp.paging -= npages;
+
+       if (pdaemon_waiters) {
+               pdaemon_waiters = 0;
+               cv_broadcast(&oomwait);
+       }
+       mutex_exit(&pdaemonmtx);
 }
 
 static bool
@@ -969,6 +982,8 @@
 
 /*
  * The Diabolical pageDaemon Director (DDD).
+ *
+ * This routine can always use better heuristics.
  */
 void
 uvm_pageout(void *arg)
@@ -976,35 +991,30 @@
        struct vm_page *pg;
        struct pool *pp, *pp_first;
        uint64_t where;
-       int timo = 0;
        int cleaned, skip, skipped;
-       bool succ = false;
+       int waspaging;
+       bool succ;
        bool lockrunning;
 
        mutex_enter(&pdaemonmtx);
        for (;;) {
-               if (succ) {
+               if (!NEED_PAGEDAEMON()) {
                        kernel_map->flags &= ~VM_MAP_WANTVA;
                        kmem_map->flags &= ~VM_MAP_WANTVA;
-                       timo = 0;
-                       if (pdaemon_waiters) {
-                               pdaemon_waiters = 0;
-                               cv_broadcast(&oomwait);
-                       }
                }
-               succ = false;
 
-               if (pdaemon_waiters == 0) {
-                       cv_timedwait(&pdaemoncv, &pdaemonmtx, timo);
-                       uvmexp.pdwoke++;
+               if (pdaemon_waiters) {
+                       pdaemon_waiters = 0;
+                       cv_broadcast(&oomwait);
                }
 
+               cv_wait(&pdaemoncv, &pdaemonmtx);
+               uvmexp.pdwoke++;
+               waspaging = uvmexp.paging;
+
                /* tell the world that we are hungry */
                kernel_map->flags |= VM_MAP_WANTVA;
                kmem_map->flags |= VM_MAP_WANTVA;
-
-               if (pdaemon_waiters == 0 && !NEED_PAGEDAEMON())
-                       continue;
                mutex_exit(&pdaemonmtx);
 
                /*
@@ -1014,7 +1024,6 @@
                 */
                pool_cache_reclaim(&pagecache);
                if (!NEED_PAGEDAEMON()) {
-                       succ = true;
                        mutex_enter(&pdaemonmtx);
                        continue;
                }
@@ -1081,7 +1090,6 @@
                 */
                pool_cache_reclaim(&pagecache);
                if (!NEED_PAGEDAEMON()) {
-                       succ = true;
                        mutex_enter(&pdaemonmtx);
                        continue;
                }
@@ -1118,13 +1126,14 @@
                 * Unfortunately, the wife just borrowed it.
                 */
 
-               if (!succ && cleaned == 0) {
+               mutex_enter(&pdaemonmtx);
+               if (!succ && cleaned == 0 && pdaemon_waiters &&
+                   uvmexp.paging == 0) {
                        rumpuser_dprintf("pagedaemoness: failed to reclaim "
                            "memory ... sleeping (deadlock?)\n");
-                       timo = hz;
+                       cv_timedwait(&pdaemoncv, &pdaemonmtx, hz);
+                       mutex_enter(&pdaemonmtx);
                }
-
-               mutex_enter(&pdaemonmtx);
        }
 
        panic("you can swap out any time you like, but you can never leave");
diff -r 10b9082c0342 -r 6ba381257532 sys/rump/librump/rumpvfs/vm_vfs.c
--- a/sys/rump/librump/rumpvfs/vm_vfs.c Tue Feb 22 18:45:10 2011 +0000
+++ b/sys/rump/librump/rumpvfs/vm_vfs.c Tue Feb 22 20:17:37 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vm_vfs.c,v 1.24 2010/12/18 11:45:09 pooka Exp $        */
+/*     $NetBSD: vm_vfs.c,v 1.25 2011/02/22 20:17:37 pooka Exp $        */
 
 /*
  * Copyright (c) 2008 Antti Kantee.  All Rights Reserved.
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_vfs.c,v 1.24 2010/12/18 11:45:09 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_vfs.c,v 1.25 2011/02/22 20:17:37 pooka Exp $");
 
 #include <sys/param.h>
 
@@ -67,7 +67,6 @@
        }
 
        uvm_pagermapout((vaddr_t)bp->b_data, npages);
-       uvm_pageout_done(pageout);
 
        /* get uobj because we need it after pages might be recycled */
        uobj = pgs[0]->uobject;
@@ -79,6 +78,8 @@
        mutex_exit(&uvm_pageqlock);
        mutex_exit(&uobj->vmobjlock);
 
+       uvm_pageout_done(pageout);
+
        if (BUF_ISWRITE(bp) && (bp->b_cflags & BC_AGE) != 0) {
                mutex_enter(bp->b_objlock);
                vwakeup(bp);



Home | Main Index | Thread Index | Old Index