Source-Changes-HG archive

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

[src/trunk]: src/sys Make page waits (WANTED vs BUSY) interlocked by pg->inte...



details:   https://anonhg.NetBSD.org/src/rev/19cc18b379d2
branches:  trunk
changeset: 849803:19cc18b379d2
user:      ad <ad%NetBSD.org@localhost>
date:      Sat Mar 14 20:23:51 2020 +0000

description:
Make page waits (WANTED vs BUSY) interlocked by pg->interlock.  Gets RW
locks out of the equation for sleep/wakeup, and allows observing+waiting
for busy pages when holding only a read lock.  Proposed on tech-kern.

diffstat:

 sys/kern/kern_synch.c               |  44 +--------------------
 sys/miscfs/genfs/genfs_io.c         |  13 ++---
 sys/rump/librump/rumpkern/ltsleep.c |  19 +--------
 sys/rump/librump/rumpkern/vm.c      |  48 +++++++++++++++++++---
 sys/sys/proc.h                      |   3 +-
 sys/ufs/lfs/lfs_pages.c             |  17 +++----
 sys/ufs/lfs/lfs_vfsops.c            |   5 +-
 sys/uvm/uvm.h                       |   9 +---
 sys/uvm/uvm_amap.c                  |  13 ++---
 sys/uvm/uvm_anon.c                  |  11 +---
 sys/uvm/uvm_aobj.c                  |  25 +++--------
 sys/uvm/uvm_bio.c                   |  10 +---
 sys/uvm/uvm_fault.c                 |  64 +++++++++++-------------------
 sys/uvm/uvm_km.c                    |  10 +--
 sys/uvm/uvm_loan.c                  |  41 ++++++-------------
 sys/uvm/uvm_page.c                  |  77 ++++++++++++++++++++++++++++++------
 sys/uvm/uvm_page.h                  |  36 +++++++++++-----
 sys/uvm/uvm_vnode.c                 |   8 +--
 18 files changed, 210 insertions(+), 243 deletions(-)

diffs (truncated from 1136 to 300 lines):

diff -r 146f718e5ba0 -r 19cc18b379d2 sys/kern/kern_synch.c
--- a/sys/kern/kern_synch.c     Sat Mar 14 19:54:06 2020 +0000
+++ b/sys/kern/kern_synch.c     Sat Mar 14 20:23:51 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_synch.c,v 1.343 2020/03/14 18:08:39 ad Exp $      */
+/*     $NetBSD: kern_synch.c,v 1.344 2020/03/14 20:23:51 ad Exp $      */
 
 /*-
  * Copyright (c) 1999, 2000, 2004, 2006, 2007, 2008, 2009, 2019, 2020
@@ -69,7 +69,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.343 2020/03/14 18:08:39 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.344 2020/03/14 20:23:51 ad Exp $");
 
 #include "opt_kstack.h"
 #include "opt_dtrace.h"
@@ -220,46 +220,6 @@
 }
 
 /*
- * XXXAD Temporary - for use of UVM only.  PLEASE DO NOT USE ELSEWHERE. 
- * Will go once there is a better solution, eg waits interlocked by
- * pg->interlock.  To wake an LWP sleeping with this, you need to hold a
- * write lock.
- */
-int
-rwtsleep(wchan_t ident, pri_t priority, const char *wmesg, int timo,
-        krwlock_t *rw)
-{
-       struct lwp *l = curlwp;
-       sleepq_t *sq;
-       kmutex_t *mp;
-       int error;
-       krw_t op;
-
-       KASSERT((l->l_pflag & LP_INTR) == 0);
-       KASSERT(ident != &lbolt);
-
-       if (sleepq_dontsleep(l)) {
-               (void)sleepq_abort(NULL, (priority & PNORELOCK) != 0);
-               if ((priority & PNORELOCK) != 0)
-                       rw_exit(rw);
-               return 0;
-       }
-
-       l->l_kpriority = true;
-       sq = sleeptab_lookup(&sleeptab, ident, &mp);
-       sleepq_enter(sq, l, mp);
-       sleepq_enqueue(sq, ident, wmesg, &sleep_syncobj);
-       op = rw_lock_op(rw);
-       rw_exit(rw);
-       error = sleepq_block(timo, priority & PCATCH);
-
-       if ((priority & PNORELOCK) == 0)
-               rw_enter(rw, op);
-
-       return error;
-}
-
-/*
  * General sleep call for situations where a wake-up is not expected.
  */
 int
diff -r 146f718e5ba0 -r 19cc18b379d2 sys/miscfs/genfs/genfs_io.c
--- a/sys/miscfs/genfs/genfs_io.c       Sat Mar 14 19:54:06 2020 +0000
+++ b/sys/miscfs/genfs/genfs_io.c       Sat Mar 14 20:23:51 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: genfs_io.c,v 1.91 2020/03/14 19:07:22 ad Exp $ */
+/*     $NetBSD: genfs_io.c,v 1.92 2020/03/14 20:23:51 ad Exp $ */
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.91 2020/03/14 19:07:22 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.92 2020/03/14 20:23:51 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -524,9 +524,6 @@
                if (i < ridx || i >= ridx + orignmempages || async) {
                        UVMHIST_LOG(ubchist, "unbusy pg %#jx offset 0x%jx",
                            (uintptr_t)pg, pg->offset,0,0);
-                       if (pg->flags & PG_WANTED) {
-                               wakeup(pg);
-                       }
                        if (pg->flags & PG_FAKE) {
                                KASSERT(overwrite);
                                uvm_pagezero(pg);
@@ -537,8 +534,9 @@
                        }
                        uvm_pagelock(pg);
                        uvm_pageenqueue(pg);
+                       uvm_pageunbusy(pg);
                        uvm_pageunlock(pg);
-                       pg->flags &= ~(PG_WANTED|PG_BUSY|PG_FAKE);
+                       pg->flags &= ~PG_FAKE;
                        UVM_PAGE_OWN(pg, NULL);
                } else if (memwrite && !overwrite &&
                    uvm_pagegetdirty(pg) == UVM_PAGE_STATUS_CLEAN) {
@@ -1093,8 +1091,7 @@
                                continue;
                        }
                        nextoff = pg->offset; /* visit this page again */
-                       pg->flags |= PG_WANTED;
-                       UVM_UNLOCK_AND_WAIT_RW(pg, slock, 0, "genput", 0);
+                       uvm_pagewait(pg, slock, "genput");
                        /*
                         * as we dropped the object lock, our cached pages can
                         * be stale.
diff -r 146f718e5ba0 -r 19cc18b379d2 sys/rump/librump/rumpkern/ltsleep.c
--- a/sys/rump/librump/rumpkern/ltsleep.c       Sat Mar 14 19:54:06 2020 +0000
+++ b/sys/rump/librump/rumpkern/ltsleep.c       Sat Mar 14 20:23:51 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ltsleep.c,v 1.35 2020/02/23 15:46:42 ad Exp $  */
+/*     $NetBSD: ltsleep.c,v 1.36 2020/03/14 20:23:51 ad Exp $  */
 
 /*
  * Copyright (c) 2009, 2010 Antti Kantee.  All Rights Reserved.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ltsleep.c,v 1.35 2020/02/23 15:46:42 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ltsleep.c,v 1.36 2020/03/14 20:23:51 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -151,21 +151,6 @@
        return rv;
 }
 
-int
-rwtsleep(wchan_t ident, pri_t prio, const char *wmesg, int timo, krwlock_t *lock)
-{
-       krw_t op = rw_write_held(lock) ? RW_WRITER : RW_READER;
-       int rv;
-
-       mutex_spin_enter(&qlock);
-       rw_exit(lock);
-       rv = sleeper(ident, timo, true);
-       if ((prio & PNORELOCK) == 0)
-               rw_enter(lock, op);
-
-       return rv;
-}
-
 void
 wakeup(wchan_t ident)
 {
diff -r 146f718e5ba0 -r 19cc18b379d2 sys/rump/librump/rumpkern/vm.c
--- a/sys/rump/librump/rumpkern/vm.c    Sat Mar 14 19:54:06 2020 +0000
+++ b/sys/rump/librump/rumpkern/vm.c    Sat Mar 14 20:23:51 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vm.c,v 1.185 2020/03/14 19:54:06 ad Exp $      */
+/*     $NetBSD: vm.c,v 1.186 2020/03/14 20:23:51 ad Exp $      */
 
 /*
  * Copyright (c) 2007-2011 Antti Kantee.  All Rights Reserved.
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.185 2020/03/14 19:54:06 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.186 2020/03/14 20:23:51 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -219,8 +219,12 @@
 
        KASSERT(rw_write_held(uobj->vmobjlock));
 
-       if (pg->flags & PG_WANTED)
+       mutex_enter(&pg->interlock);
+       if (pg->pqflags & PQ_WANTED) {
+               pg->pqflags &= ~PQ_WANTED;
                wakeup(pg);
+       }
+       mutex_exit(&pg->interlock);
 
        uobj->uo_npages--;
        pg2 = radix_tree_remove_node(&uobj->uo_pages, pg->offset >> PAGE_SHIFT);
@@ -682,16 +686,44 @@
                        continue;
 
                KASSERT(pg->flags & PG_BUSY);
-               if (pg->flags & PG_WANTED)
-                       wakeup(pg);
-               if (pg->flags & PG_RELEASED)
+               if (pg->flags & PG_RELEASED) {
                        uvm_pagefree(pg);
-               else
-                       pg->flags &= ~(PG_WANTED|PG_BUSY);
+               } else {
+                       uvm_pagelock(pg);
+                       uvm_pageunbusy(pg);
+                       uvm_pageunlock(pg);
+               }
        }
 }
 
 void
+uvm_pagewait(struct vm_page *pg, krwlock_t *lock, const char *wmesg)
+{
+
+       KASSERT(rw_lock_held(lock));
+       KASSERT((pg->flags & PG_BUSY) != 0);
+
+       mutex_enter(&pg->interlock);
+       pg->pqflags |= PQ_WANTED;
+       rw_exit(lock);
+       UVM_UNLOCK_AND_WAIT(pg, &pg->interlock, false, wmesg, 0);
+}
+
+void
+uvm_pageunbusy(struct vm_page *pg)
+{
+
+       KASSERT((pg->flags & PG_BUSY) != 0);
+       KASSERT(mutex_owned(&pg->interlock));
+
+       if ((pg->pqflags & PQ_WANTED) != 0) {
+               pg->pqflags &= ~PQ_WANTED;
+               wakeup(pg);
+       }
+       pg->flags &= ~PG_BUSY;
+}
+
+void
 uvm_estimatepageable(int *active, int *inactive)
 {
 
diff -r 146f718e5ba0 -r 19cc18b379d2 sys/sys/proc.h
--- a/sys/sys/proc.h    Sat Mar 14 19:54:06 2020 +0000
+++ b/sys/sys/proc.h    Sat Mar 14 20:23:51 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: proc.h,v 1.359 2020/02/23 15:46:42 ad Exp $    */
+/*     $NetBSD: proc.h,v 1.360 2020/03/14 20:23:51 ad Exp $    */
 
 /*-
  * Copyright (c) 2006, 2007, 2008, 2020 The NetBSD Foundation, Inc.
@@ -513,7 +513,6 @@
 
 int    tsleep(wchan_t, pri_t, const char *, int);
 int    mtsleep(wchan_t, pri_t, const char *, int, kmutex_t *);
-int    rwtsleep(wchan_t, pri_t, const char *, int, krwlock_t *);
 void   wakeup(wchan_t);
 int    kpause(const char *, bool, int, kmutex_t *);
 void   exit1(struct lwp *, int, int) __dead;
diff -r 146f718e5ba0 -r 19cc18b379d2 sys/ufs/lfs/lfs_pages.c
--- a/sys/ufs/lfs/lfs_pages.c   Sat Mar 14 19:54:06 2020 +0000
+++ b/sys/ufs/lfs/lfs_pages.c   Sat Mar 14 20:23:51 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_pages.c,v 1.22 2020/02/23 15:46:42 ad Exp $        */
+/*     $NetBSD: lfs_pages.c,v 1.23 2020/03/14 20:23:51 ad Exp $        */
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2019 The NetBSD Foundation, Inc.
@@ -60,7 +60,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lfs_pages.c,v 1.22 2020/02/23 15:46:42 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lfs_pages.c,v 1.23 2020/03/14 20:23:51 ad Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -167,8 +167,7 @@
        lastpg = pg;
 #endif
 
-       pg->flags |= PG_WANTED;
-       UVM_UNLOCK_AND_WAIT_RW(pg, vp->v_uobj.vmobjlock, 0, "lfsput", 0);
+       uvm_pagewait(pg, vp->v_uobj.vmobjlock, "lfsput");
        rw_enter(vp->v_uobj.vmobjlock, RW_WRITER);
 }
 
@@ -349,9 +348,9 @@
                                        pg->flags |= PG_DELWRI;
                                }
                        }
-                       if (pg->flags & PG_WANTED)
-                               wakeup(pg);
-                       pg->flags &= ~(PG_WANTED|PG_BUSY);
+                       uvm_pagelock(pg);
+                       uvm_pageunbusy(pg);
+                       uvm_pageunlock(pg);
                        UVM_PAGE_OWN(pg, NULL);
                }
 
@@ -495,9 +494,7 @@
                        pg = uvm_pagelookup(&vp->v_uobj, off);
                        KASSERT(pg != NULL);
                        while (pg->flags & PG_BUSY) {
-                               pg->flags |= PG_WANTED;
-                               UVM_UNLOCK_AND_WAIT_RW(pg, vp->v_uobj.vmobjlock, 0,



Home | Main Index | Thread Index | Old Index