Source-Changes-HG archive

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

[src/yamt-pagecache]: src/sys - use mutex obj for pageable object



details:   https://anonhg.NetBSD.org/src/rev/9ec5749b5caa
branches:  yamt-pagecache
changeset: 770834:9ec5749b5caa
user:      yamt <yamt%NetBSD.org@localhost>
date:      Fri Nov 18 00:57:33 2011 +0000

description:
- use mutex obj for pageable object
- add a function to wait for a mutex obj being available
- replace some "livelock" kpauses with it

diffstat:

 sys/kern/kern_mutex_obj.c |  52 ++++++++++++++++++++++++++++++++++++++++++++--
 sys/sys/mutex.h           |   4 ++-
 sys/uvm/uvm_aobj.c        |  15 +++++--------
 sys/uvm/uvm_loan.c        |   7 ++---
 sys/uvm/uvm_page.c        |  15 ++++---------
 sys/uvm/uvm_page.h        |   3 +-
 sys/uvm/uvm_pdaemon.c     |  29 ++++++++------------------
 7 files changed, 77 insertions(+), 48 deletions(-)

diffs (truncated from 304 to 300 lines):

diff -r 1654c83c6c78 -r 9ec5749b5caa sys/kern/kern_mutex_obj.c
--- a/sys/kern/kern_mutex_obj.c Fri Nov 18 00:51:28 2011 +0000
+++ b/sys/kern/kern_mutex_obj.c Fri Nov 18 00:57:33 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_mutex_obj.c,v 1.5 2011/09/27 01:02:38 jym Exp $   */
+/*     $NetBSD: kern_mutex_obj.c,v 1.5.2.1 2011/11/18 00:57:33 yamt Exp $      */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_mutex_obj.c,v 1.5 2011/09/27 01:02:38 jym Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_mutex_obj.c,v 1.5.2.1 2011/11/18 00:57:33 yamt Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -134,10 +134,56 @@
            "%s: lock %p: mo->mo_refcnt (%#x) == 0",
             __func__, mo, mo->mo_refcnt);
 
-       if (atomic_dec_uint_nv(&mo->mo_refcnt) > 0) {
+       /*
+        * if mo_refcnt is 1, no one except us have a reference to it and
+        * thus it's stable.
+        */
+       if (mo->mo_refcnt != 1 && atomic_dec_uint_nv(&mo->mo_refcnt) > 0) {
                return false;
        }
        mutex_destroy(&mo->mo_lock);
        pool_cache_put(mutex_obj_cache, mo);
        return true;
 }
+
+/*
+ * mutex_obj_pause:
+ *
+ *     Pause until lock1 is available.
+ *     Temporarily release and reacquire lock2.
+ *
+ *     Typically used when we need to acquire locks in a reversed order
+ *     and trylock failed.
+ */
+void
+mutex_obj_pause(kmutex_t *lock1, kmutex_t *lock2)
+{
+
+       KASSERT(mutex_owned(lock2));
+       mutex_obj_hold(lock1);
+       mutex_exit(lock2);
+       mutex_enter(lock1);
+       mutex_exit(lock1);
+       mutex_obj_free(lock1);
+       mutex_enter(lock2);
+}
+
+/*
+ * mutex_obj_alloc_kernel_obj_lock:
+ *
+ *     mutex_obj_alloc for kernel object lock.
+ *     used for bootstrap.
+ */
+kmutex_t *
+mutex_obj_alloc_kernel_obj_lock(kmutex_type_t type, int ipl)
+{
+       static struct kmutexobj kernel_obj_lock;
+       struct kmutexobj *mo = &kernel_obj_lock;
+
+       KASSERT(mo->mo_refcnt == 0);
+       mutex_obj_ctor(NULL, mo, 0);
+       mutex_init(&mo->mo_lock, type, ipl);
+       mo->mo_refcnt = 1;
+       return (kmutex_t *)mo;
+}
+
diff -r 1654c83c6c78 -r 9ec5749b5caa sys/sys/mutex.h
--- a/sys/sys/mutex.h   Fri Nov 18 00:51:28 2011 +0000
+++ b/sys/sys/mutex.h   Fri Nov 18 00:57:33 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mutex.h,v 1.20 2010/02/08 09:54:27 skrll Exp $ */
+/*     $NetBSD: mutex.h,v 1.20.10.1 2011/11/18 00:57:33 yamt Exp $     */
 
 /*-
  * Copyright (c) 2002, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -210,6 +210,8 @@
 kmutex_t *mutex_obj_alloc(kmutex_type_t, int);
 void   mutex_obj_hold(kmutex_t *);
 bool   mutex_obj_free(kmutex_t *);
+void   mutex_obj_pause(kmutex_t *, kmutex_t *);
+kmutex_t *mutex_obj_alloc_kernel_obj_lock(kmutex_type_t, int);
 
 #endif /* _KERNEL */
 
diff -r 1654c83c6c78 -r 9ec5749b5caa sys/uvm/uvm_aobj.c
--- a/sys/uvm/uvm_aobj.c        Fri Nov 18 00:51:28 2011 +0000
+++ b/sys/uvm/uvm_aobj.c        Fri Nov 18 00:57:33 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_aobj.c,v 1.116.2.4 2011/11/13 01:18:02 yamt Exp $  */
+/*     $NetBSD: uvm_aobj.c,v 1.116.2.5 2011/11/18 00:57:33 yamt Exp $  */
 
 /*
  * Copyright (c) 1998 Chuck Silvers, Charles D. Cranor and
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_aobj.c,v 1.116.2.4 2011/11/13 01:18:02 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_aobj.c,v 1.116.2.5 2011/11/18 00:57:33 yamt Exp $");
 
 #include "opt_uvmhist.h"
 
@@ -437,7 +437,6 @@
 uao_create(vsize_t size, int flags)
 {
        static struct uvm_aobj kernel_object_store;
-       static kmutex_t kernel_object_lock;
        static int kobj_alloced = 0;
        pgoff_t pages = round_page(size) >> PAGE_SHIFT;
        struct uvm_aobj *aobj;
@@ -506,8 +505,8 @@
        uvm_obj_init(&aobj->u_obj, &aobj_pager, !kernobj, refs);
        if (__predict_false(kernobj)) {
                /* Initialisation only once, for UAO_FLAG_KERNOBJ. */
-               mutex_init(&kernel_object_lock, MUTEX_DEFAULT, IPL_NONE);
-               uvm_obj_setlock(&aobj->u_obj, &kernel_object_lock);
+               uvm_obj_setlock(&aobj->u_obj, 
+                   mutex_obj_alloc_kernel_obj_lock(MUTEX_DEFAULT, IPL_NONE));
        }
 
        /*
@@ -1195,8 +1194,8 @@
         * walk the list of all aobjs.
         */
 
+       mutex_enter(&uao_list_lock);
 restart:
-       mutex_enter(&uao_list_lock);
        for (aobj = LIST_FIRST(&uao_list);
             aobj != NULL;
             aobj = nextaobj) {
@@ -1208,9 +1207,7 @@
                 */
 
                if (!mutex_tryenter(aobj->u_obj.vmobjlock)) {
-                       mutex_exit(&uao_list_lock);
-                       /* XXX Better than yielding but inadequate. */
-                       kpause("livelock", false, 1, NULL);
+                       mutex_obj_pause(aobj->u_obj.vmobjlock, &uao_list_lock);
                        goto restart;
                }
 
diff -r 1654c83c6c78 -r 9ec5749b5caa sys/uvm/uvm_loan.c
--- a/sys/uvm/uvm_loan.c        Fri Nov 18 00:51:28 2011 +0000
+++ b/sys/uvm/uvm_loan.c        Fri Nov 18 00:57:33 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_loan.c,v 1.81.2.2 2011/11/06 22:05:00 yamt Exp $   */
+/*     $NetBSD: uvm_loan.c,v 1.81.2.3 2011/11/18 00:57:33 yamt Exp $   */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_loan.c,v 1.81.2.2 2011/11/06 22:05:00 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_loan.c,v 1.81.2.3 2011/11/18 00:57:33 yamt Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -983,8 +983,7 @@
                        if (mutex_tryenter(slock)) {
                                break;
                        }
-                       /* XXX Better than yielding but inadequate. */
-                       kpause("livelock", false, 1, &uvm_pageqlock);
+                       mutex_obj_pause(slock, &uvm_pageqlock);
                        slock = NULL;
                }
 
diff -r 1654c83c6c78 -r 9ec5749b5caa sys/uvm/uvm_page.c
--- a/sys/uvm/uvm_page.c        Fri Nov 18 00:51:28 2011 +0000
+++ b/sys/uvm/uvm_page.c        Fri Nov 18 00:57:33 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_page.c,v 1.178.2.5 2011/11/13 01:18:02 yamt Exp $  */
+/*     $NetBSD: uvm_page.c,v 1.178.2.6 2011/11/18 00:57:33 yamt Exp $  */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.178.2.5 2011/11/13 01:18:02 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.178.2.6 2011/11/18 00:57:33 yamt Exp $");
 
 #include "opt_ddb.h"
 #include "opt_uvmhist.h"
@@ -2057,17 +2057,12 @@
 bool
 uvm_page_locked_p(struct vm_page *pg)
 {
+       kmutex_t * const lock = uvm_page_getlock(pg);
 
-       if (pg->uobject != NULL) {
-               return mutex_owned(pg->uobject->vmobjlock);
-       }
-       if (pg->uanon != NULL) {
-               return mutex_owned(pg->uanon->an_lock);
-       }
-       return true;
+       return lock == NULL || mutex_owned(lock);
 }
 
-static kmutex_t *
+kmutex_t *
 uvm_page_getlock(struct vm_page *pg)
 {
 
diff -r 1654c83c6c78 -r 9ec5749b5caa sys/uvm/uvm_page.h
--- a/sys/uvm/uvm_page.h        Fri Nov 18 00:51:28 2011 +0000
+++ b/sys/uvm/uvm_page.h        Fri Nov 18 00:57:33 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_page.h,v 1.73.2.5 2011/11/14 14:21:41 yamt Exp $   */
+/*     $NetBSD: uvm_page.h,v 1.73.2.6 2011/11/18 00:57:34 yamt Exp $   */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -297,6 +297,7 @@
 bool uvm_pagecheckdirty(struct vm_page *, bool);
 bool uvm_pagereadonly_p(struct vm_page *);
 bool uvm_page_locked_p(struct vm_page *);
+kmutex_t *uvm_page_getlock(struct vm_page *);
 bool uvm_page_samelock_p(struct vm_page *, struct vm_page *);
 
 /*
diff -r 1654c83c6c78 -r 9ec5749b5caa sys/uvm/uvm_pdaemon.c
--- a/sys/uvm/uvm_pdaemon.c     Fri Nov 18 00:51:28 2011 +0000
+++ b/sys/uvm/uvm_pdaemon.c     Fri Nov 18 00:57:33 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_pdaemon.c,v 1.103.2.1 2011/11/02 21:54:01 yamt Exp $       */
+/*     $NetBSD: uvm_pdaemon.c,v 1.103.2.2 2011/11/18 00:57:34 yamt Exp $       */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_pdaemon.c,v 1.103.2.1 2011/11/02 21:54:01 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_pdaemon.c,v 1.103.2.2 2011/11/18 00:57:34 yamt Exp $");
 
 #include "opt_uvmhist.h"
 #include "opt_readahead.h"
@@ -416,23 +416,14 @@
 uvmpd_trylockowner(struct vm_page *pg)
 {
        struct uvm_object *uobj = pg->uobject;
-       kmutex_t *slock;
+       kmutex_t *lock;
 
        KASSERT(mutex_owned(&uvm_pageqlock));
-
-       if (uobj != NULL) {
-               slock = uobj->vmobjlock;
-       } else {
-               struct vm_anon *anon = pg->uanon;
-
-               KASSERT(anon != NULL);
-               slock = anon->an_lock;
-       }
-
-       if (!mutex_tryenter(slock)) {
+       lock = uvm_page_getlock(pg);
+       KASSERT(lock != NULL);
+       if (!mutex_tryenter(lock)) {
                return NULL;
        }
-
        if (uobj == NULL) {
 
                /*
@@ -447,7 +438,7 @@
                }
        }
 
-       return slock;
+       return lock;
 }
 
 #if defined(VMSWAP)
@@ -739,10 +730,8 @@
                         */
                        lockownerfail++;
                        if (lockownerfail > UVMPD_NUMTRYLOCKOWNER) {
-                               mutex_exit(&uvm_pageqlock);
-                               /* XXX Better than yielding but inadequate. */
-                               kpause("livelock", false, 1, NULL);
-                               mutex_enter(&uvm_pageqlock);
+                               mutex_obj_pause(uvm_page_getlock(p),



Home | Main Index | Thread Index | Old Index