Source-Changes-HG archive

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

[src/trunk]: src/sys - Fix a few possible locking issues in execve1() and exi...



details:   https://anonhg.NetBSD.org/src/rev/07ba3460fe10
branches:  trunk
changeset: 759851:07ba3460fe10
user:      rmind <rmind%NetBSD.org@localhost>
date:      Sat Dec 18 01:36:19 2010 +0000

description:
- Fix a few possible locking issues in execve1() and exit1().  Add a note
  that scheduler locks are special in this regard - adaptive locks cannot
  be in the path due to turnstiles.  Randomly spotted/reported by uebayasi@.
- Remove unused lwp_relock() and replace lwp_lock_retry() by simplifying
  lwp_lock() and sleepq_enter() a little.
- Give alllwp its own cache-line and mark lwp_cache pointer as read-mostly.

OK ad@

diffstat:

 sys/kern/kern_exec.c               |   6 ++-
 sys/kern/kern_exit.c               |   6 ++-
 sys/kern/kern_lwp.c                |  71 +++++--------------------------------
 sys/kern/kern_timeout.c            |   5 +-
 sys/kern/sys_select.c              |   8 +--
 sys/rump/librump/rumpkern/sleepq.c |  25 +++++-------
 sys/sys/lwp.h                      |  19 +++++----
 sys/sys/sleepq.h                   |  17 ++------
 8 files changed, 50 insertions(+), 107 deletions(-)

diffs (truncated from 374 to 300 lines):

diff -r be62427f5dac -r 07ba3460fe10 sys/kern/kern_exec.c
--- a/sys/kern/kern_exec.c      Sat Dec 18 01:18:48 2010 +0000
+++ b/sys/kern/kern_exec.c      Sat Dec 18 01:36:19 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_exec.c,v 1.303 2010/11/30 10:43:05 dholland Exp $ */
+/*     $NetBSD: kern_exec.c,v 1.304 2010/12/18 01:36:19 rmind Exp $    */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.303 2010/11/30 10:43:05 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.304 2010/12/18 01:36:19 rmind Exp $");
 
 #include "opt_ktrace.h"
 #include "opt_modular.h"
@@ -1165,8 +1165,10 @@
                l->l_stat = LSSTOP;
                p->p_stat = SSTOP;
                p->p_nrlwps--;
+               lwp_unlock(l);
                mutex_exit(p->p_lock);
                mutex_exit(proc_lock);
+               lwp_lock(l);
                mi_switch(l);
                ksiginfo_queue_drain(&kq);
                KERNEL_LOCK(l->l_biglocks, l);
diff -r be62427f5dac -r 07ba3460fe10 sys/kern/kern_exit.c
--- a/sys/kern/kern_exit.c      Sat Dec 18 01:18:48 2010 +0000
+++ b/sys/kern/kern_exit.c      Sat Dec 18 01:36:19 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_exit.c,v 1.230 2010/07/07 01:30:37 chs Exp $      */
+/*     $NetBSD: kern_exit.c,v 1.231 2010/12/18 01:36:19 rmind Exp $    */
 
 /*-
  * Copyright (c) 1998, 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.230 2010/07/07 01:30:37 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.231 2010/12/18 01:36:19 rmind Exp $");
 
 #include "opt_ktrace.h"
 #include "opt_perfctrs.h"
@@ -244,7 +244,9 @@
                lwp_lock(l);
                p->p_nrlwps--;
                l->l_stat = LSSTOP;
+               lwp_unlock(l);
                mutex_exit(p->p_lock);
+               lwp_lock(l);
                mi_switch(l);
                KERNEL_LOCK(l->l_biglocks, l);
                mutex_enter(p->p_lock);
diff -r be62427f5dac -r 07ba3460fe10 sys/kern/kern_lwp.c
--- a/sys/kern/kern_lwp.c       Sat Dec 18 01:18:48 2010 +0000
+++ b/sys/kern/kern_lwp.c       Sat Dec 18 01:36:19 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_lwp.c,v 1.151 2010/07/07 01:30:37 chs Exp $       */
+/*     $NetBSD: kern_lwp.c,v 1.152 2010/12/18 01:36:19 rmind Exp $     */
 
 /*-
  * Copyright (c) 2001, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -153,9 +153,11 @@
  *     each field are documented in sys/lwp.h.
  *
  *     State transitions must be made with the LWP's general lock held,
- *     and may cause the LWP's lock pointer to change. Manipulation of
+ *     and may cause the LWP's lock pointer to change.  Manipulation of
  *     the general lock is not performed directly, but through calls to
- *     lwp_lock(), lwp_relock() and similar.
+ *     lwp_lock(), lwp_unlock() and others.  It should be noted that the
+ *     adaptive locks are not allowed to be released while the LWP's lock
+ *     is being held (unlike for other spin-locks).
  *
  *     States and their associated locks:
  *
@@ -209,7 +211,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.151 2010/07/07 01:30:37 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.152 2010/12/18 01:36:19 rmind Exp $");
 
 #include "opt_ddb.h"
 #include "opt_lockdebug.h"
@@ -242,8 +244,8 @@
 #include <uvm/uvm_extern.h>
 #include <uvm/uvm_object.h>
 
-struct lwplist         alllwp = LIST_HEAD_INITIALIZER(alllwp);
-static pool_cache_t    lwp_cache;
+static pool_cache_t    lwp_cache       __read_mostly;
+struct lwplist         alllwp          __cacheline_aligned;
 
 /* DTrace proc provider probes */
 SDT_PROBE_DEFINE(proc,,,lwp_create,
@@ -284,6 +286,7 @@
 lwpinit(void)
 {
 
+       LIST_INIT(&alllwp);
        lwpinit_specificdata();
        lwp_sys_init();
        lwp_cache = pool_cache_init(sizeof(lwp_t), MIN_LWP_ALIGNMENT, 0, 0,
@@ -1242,40 +1245,6 @@
 }
 
 /*
- * Lock an LWP.
- */
-kmutex_t *
-lwp_lock_retry(struct lwp *l, kmutex_t *old)
-{
-
-       /*
-        * XXXgcc ignoring kmutex_t * volatile on i386
-        *
-        * gcc version 4.1.2 20061021 prerelease (NetBSD nb1 20061021)
-        */
-#if 1
-       while (l->l_mutex != old) {
-#else
-       for (;;) {
-#endif
-               mutex_spin_exit(old);
-               old = l->l_mutex;
-               mutex_spin_enter(old);
-
-               /*
-                * mutex_enter() will have posted a read barrier.  Re-test
-                * l->l_mutex.  If it has changed, we need to try again.
-                */
-#if 1
-       }
-#else
-       } while (__predict_false(l->l_mutex != old));
-#endif
-
-       return old;
-}
-
-/*
  * Lend a new mutex to an LWP.  The old mutex must be held.
  */
 void
@@ -1297,7 +1266,7 @@
 {
        kmutex_t *old;
 
-       KASSERT(mutex_owned(l->l_mutex));
+       KASSERT(lwp_locked(l, NULL));
 
        old = l->l_mutex;
        membar_exit();
@@ -1305,25 +1274,6 @@
        mutex_spin_exit(old);
 }
 
-/*
- * Acquire a new mutex, and donate it to an LWP.  The LWP must already be
- * locked.
- */
-void
-lwp_relock(struct lwp *l, kmutex_t *new)
-{
-       kmutex_t *old;
-
-       KASSERT(mutex_owned(l->l_mutex));
-
-       old = l->l_mutex;
-       if (old != new) {
-               mutex_spin_enter(new);
-               l->l_mutex = new;
-               mutex_spin_exit(old);
-       }
-}
-
 int
 lwp_trylock(struct lwp *l)
 {
@@ -1346,7 +1296,6 @@
        (*l->l_syncobj->sobj_unsleep)(l, cleanup);
 }
 
-
 /*
  * Handle exceptions for mi_userret().  Called if a member of LW_USERRET is
  * set.
diff -r be62427f5dac -r 07ba3460fe10 sys/kern/kern_timeout.c
--- a/sys/kern/kern_timeout.c   Sat Dec 18 01:18:48 2010 +0000
+++ b/sys/kern/kern_timeout.c   Sat Dec 18 01:36:19 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_timeout.c,v 1.44 2009/03/21 13:11:14 ad Exp $     */
+/*     $NetBSD: kern_timeout.c,v 1.45 2010/12/18 01:36:19 rmind Exp $  */
 
 /*-
  * Copyright (c) 2003, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_timeout.c,v 1.44 2009/03/21 13:11:14 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_timeout.c,v 1.45 2010/12/18 01:36:19 rmind Exp $");
 
 /*
  * Timeouts are kept in a hierarchical timing wheel.  The c_time is the
@@ -87,6 +87,7 @@
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/callout.h>
+#include <sys/lwp.h>
 #include <sys/mutex.h>
 #include <sys/proc.h>
 #include <sys/sleepq.h>
diff -r be62427f5dac -r 07ba3460fe10 sys/kern/sys_select.c
--- a/sys/kern/sys_select.c     Sat Dec 18 01:18:48 2010 +0000
+++ b/sys/kern/sys_select.c     Sat Dec 18 01:36:19 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sys_select.c,v 1.28 2010/10/15 05:39:19 rmind Exp $    */
+/*     $NetBSD: sys_select.c,v 1.29 2010/12/18 01:36:19 rmind Exp $    */
 
 /*-
  * Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
@@ -84,21 +84,19 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_select.c,v 1.28 2010/10/15 05:39:19 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_select.c,v 1.29 2010/12/18 01:36:19 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/filedesc.h>
-#include <sys/ioctl.h>
 #include <sys/file.h>
 #include <sys/proc.h>
 #include <sys/socketvar.h>
 #include <sys/signalvar.h>
 #include <sys/uio.h>
 #include <sys/kernel.h>
-#include <sys/stat.h>
+#include <sys/lwp.h>
 #include <sys/poll.h>
-#include <sys/vnode.h>
 #include <sys/mount.h>
 #include <sys/syscallargs.h>
 #include <sys/cpu.h>
diff -r be62427f5dac -r 07ba3460fe10 sys/rump/librump/rumpkern/sleepq.c
--- a/sys/rump/librump/rumpkern/sleepq.c        Sat Dec 18 01:18:48 2010 +0000
+++ b/sys/rump/librump/rumpkern/sleepq.c        Sat Dec 18 01:36:19 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sleepq.c,v 1.8 2010/07/23 19:14:14 pooka Exp $ */
+/*     $NetBSD: sleepq.c,v 1.9 2010/12/18 01:36:20 rmind Exp $ */
 
 /*
  * Copyright (c) 2008 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sleepq.c,v 1.8 2010/07/23 19:14:14 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sleepq.c,v 1.9 2010/12/18 01:36:20 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/condvar.h>
@@ -161,18 +161,15 @@
        return NULL;
 }
 
-/*
- * XXX: used only by callout, therefore here.  should try to use
- * one in kern_lwp directly.
- */
-kmutex_t *
-lwp_lock_retry(struct lwp *l, kmutex_t *old)
+void
+lwp_unlock_to(struct lwp *l, kmutex_t *new)
 {
+       kmutex_t *old;
 
-       while (l->l_mutex != old) {
-               mutex_spin_exit(old);
-               old = l->l_mutex;
-               mutex_spin_enter(old);
-       }
-       return old;
+       KASSERT(mutex_owned(l->l_mutex));
+
+       old = l->l_mutex;
+       membar_exit();
+       l->l_mutex = new;
+       mutex_spin_exit(old);
 }
diff -r be62427f5dac -r 07ba3460fe10 sys/sys/lwp.h
--- a/sys/sys/lwp.h     Sat Dec 18 01:18:48 2010 +0000
+++ b/sys/sys/lwp.h     Sat Dec 18 01:36:19 2010 +0000



Home | Main Index | Thread Index | Old Index