summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2015-08-14 06:14:20 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2015-08-14 06:14:20 +0000
commit68704befa2a2cb39d5082887c61ae48a17125d96 (patch)
tree3db66de6fa463f2868f5edb2ce5f6f7aadf6c3a3 /sys/arch
parentfc5e6e905c0592dfb3e47078a194cb111c88b040 (diff)
replace the asm mutexes with a c implementation.
there's no real functional advantage to this, except that it will make it easier to add deadlock detection to the code. this is modelled on the c mutex implementation thats on alpha, mips64, and hppa. ok mpi@ kettenis@
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/macppc/macppc/genassym.cf7
-rw-r--r--sys/arch/powerpc/conf/files.powerpc4
-rw-r--r--sys/arch/powerpc/include/lock.h4
-rw-r--r--sys/arch/powerpc/include/mutex.h10
-rw-r--r--sys/arch/powerpc/powerpc/lock_machdep.c4
-rw-r--r--sys/arch/powerpc/powerpc/mutex.S182
-rw-r--r--sys/arch/powerpc/powerpc/mutex.c150
7 files changed, 162 insertions, 199 deletions
diff --git a/sys/arch/macppc/macppc/genassym.cf b/sys/arch/macppc/macppc/genassym.cf
index ba2372e3749..8d95e9b4704 100644
--- a/sys/arch/macppc/macppc/genassym.cf
+++ b/sys/arch/macppc/macppc/genassym.cf
@@ -1,4 +1,4 @@
-# $OpenBSD: genassym.cf,v 1.24 2014/09/06 10:45:29 mpi Exp $
+# $OpenBSD: genassym.cf,v 1.25 2015/08/14 06:14:19 dlg Exp $
#
# Copyright (c) 1982, 1990 The Regents of the University of California.
# All rights reserved.
@@ -97,8 +97,3 @@ member ci_disisave
ifdef DIAGNOSTIC
member ci_mutex_level
endif
-
-struct mutex
-member mtx_wantipl
-member mtx_oldcpl
-member mtx_owner
diff --git a/sys/arch/powerpc/conf/files.powerpc b/sys/arch/powerpc/conf/files.powerpc
index 1394b63f07d..58212d1e670 100644
--- a/sys/arch/powerpc/conf/files.powerpc
+++ b/sys/arch/powerpc/conf/files.powerpc
@@ -1,4 +1,4 @@
-# $OpenBSD: files.powerpc,v 1.52 2015/07/17 22:52:29 tedu Exp $
+# $OpenBSD: files.powerpc,v 1.53 2015/08/14 06:14:19 dlg Exp $
#
file arch/powerpc/powerpc/setjmp.S ddb
@@ -13,8 +13,8 @@ file arch/powerpc/powerpc/process_machdep.c
file arch/powerpc/powerpc/sys_machdep.c
file arch/powerpc/powerpc/trap.c
file arch/powerpc/powerpc/vm_machdep.c
+file arch/powerpc/powerpc/mutex.c
file arch/powerpc/powerpc/lock_machdep.c multiprocessor
-file arch/powerpc/powerpc/mutex.S
file arch/powerpc/powerpc/intr.c
file arch/powerpc/powerpc/softintr.c
diff --git a/sys/arch/powerpc/include/lock.h b/sys/arch/powerpc/include/lock.h
index 2d979d1d4fb..a533cbae429 100644
--- a/sys/arch/powerpc/include/lock.h
+++ b/sys/arch/powerpc/include/lock.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: lock.h,v 1.6 2015/06/26 12:46:13 dlg Exp $ */
+/* $OpenBSD: lock.h,v 1.7 2015/08/14 06:14:19 dlg Exp $ */
/* $NetBSD: lock.h,v 1.8 2005/12/28 19:09:29 perry Exp $ */
/*-
@@ -37,4 +37,6 @@
#ifndef _POWERPC_LOCK_H_
#define _POWERPC_LOCK_H_
+#define SPINLOCK_SPIN_HOOK do { } while (0)
+
#endif /* _POWERPC_LOCK_H_ */
diff --git a/sys/arch/powerpc/include/mutex.h b/sys/arch/powerpc/include/mutex.h
index 6dec10b9b6b..8f6f2f1d57b 100644
--- a/sys/arch/powerpc/include/mutex.h
+++ b/sys/arch/powerpc/include/mutex.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mutex.h,v 1.4 2014/03/29 18:09:30 guenther Exp $ */
+/* $OpenBSD: mutex.h,v 1.5 2015/08/14 06:14:19 dlg Exp $ */
/*
* Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
@@ -28,9 +28,9 @@
#define _POWERPC_MUTEX_H_
struct mutex {
- int mtx_wantipl;
- int mtx_oldcpl;
volatile void *mtx_owner;
+ int mtx_wantipl;
+ int mtx_oldipl;
};
/*
@@ -47,7 +47,7 @@ struct mutex {
#define __MUTEX_IPL(ipl) (ipl)
#endif
-#define MUTEX_INITIALIZER(ipl) { __MUTEX_IPL((ipl)), 0, NULL }
+#define MUTEX_INITIALIZER(ipl) { NULL, __MUTEX_IPL(ipl), IPL_NONE }
void __mtx_init(struct mutex *, int);
#define mtx_init(mtx, ipl) __mtx_init((mtx), __MUTEX_IPL((ipl)))
@@ -67,6 +67,6 @@ void __mtx_init(struct mutex *, int);
#define MUTEX_ASSERT_UNLOCKED(mtx) do { } while (0)
#endif
-#define MUTEX_OLDIPL(mtx) (mtx)->mtx_oldcpl
+#define MUTEX_OLDIPL(mtx) ((mtx)->mtx_oldipl)
#endif
diff --git a/sys/arch/powerpc/powerpc/lock_machdep.c b/sys/arch/powerpc/powerpc/lock_machdep.c
index 67d737d8a51..45d1df387ac 100644
--- a/sys/arch/powerpc/powerpc/lock_machdep.c
+++ b/sys/arch/powerpc/powerpc/lock_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lock_machdep.c,v 1.2 2015/06/26 12:46:13 dlg Exp $ */
+/* $OpenBSD: lock_machdep.c,v 1.3 2015/08/14 06:14:19 dlg Exp $ */
/*
* Copyright (c) 2007 Artur Grabowski <art@openbsd.org>
@@ -42,8 +42,6 @@ __mp_lock_init(struct __mp_lock *lock)
extern int __mp_lock_spinout;
#endif
-#define SPINLOCK_SPIN_HOOK /**/
-
static __inline void
__mp_lock_spin(struct __mp_lock *mpl)
{
diff --git a/sys/arch/powerpc/powerpc/mutex.S b/sys/arch/powerpc/powerpc/mutex.S
deleted file mode 100644
index d597d0218c4..00000000000
--- a/sys/arch/powerpc/powerpc/mutex.S
+++ /dev/null
@@ -1,182 +0,0 @@
-/* $OpenBSD: mutex.S,v 1.16 2014/06/18 18:42:29 kettenis Exp $ */
-
-/*
- * Copyright (c) 2007 Dale Rahn
- * Copyright (c) 2007 Mark Kettenis
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "assym.h"
-
-#include <machine/asm.h>
-
-/* XXX */
-#define GET_CPUINFO(r) mfsprg r,0
-
-ENTRY(__mtx_init)
- li %r5,0
- stw %r4,MTX_WANTIPL(%r3)
- stw %r5,MTX_OLDCPL(%r3)
- stw %r5,MTX_OWNER(%r3)
- blr
-
-
-ENTRY(mtx_enter)
- stwu %r1,-16(%r1) # reserve stack
- mflr %r0
- stw %r0,20(%r1) # save return address
-.L_retry:
- stw %r3, 12(%r1)
- lwz %r3,MTX_WANTIPL(%r3) # load new ipl
- bl _C_LABEL(splraise)
- mr %r7, %r3
- GET_CPUINFO(%r4)
- lwz %r3,12(%r1)
- li %r5,MTX_OWNER # load offset constant
- lwarx %r6,%r5,%r3 # load reserve owner
- cmpwi 0,%r6,0 # test owner == 0
- beq+ 0,.L_mutex_free # if owner == 0 branch free
-.L_mutex_locked:
-#ifdef DIAGNOSTIC
- cmpl 0,%r4,%r6
- beq- .L_mutex_selflocked
-#endif
- stw %r3,12(%r1) # save mtx during lcsplx
- la %r4,12(%r1)
- stwcx. %r3,0,%r4 # unreserve owner
- mr %r3,%r7 # move old cpl to arg0
- bl _C_LABEL(lcsplx) # call splx on old cpl
- lwz %r3,12(%r1)
- b .L_retry
-
-.L_mutex_free:
- stwcx. %r4,%r5,%r3 # old owner was 0 cond store
- bne- .L_mutex_locked # branch if reserve cancelled
- isync # memory barrier
-#ifdef DIAGNOSTIC
- lwz %r6,CI_MUTEX_LEVEL(%r4)
- addi %r6,%r6,1 # curpcu->ci_mutex_level++
- stw %r6,CI_MUTEX_LEVEL(%r4)
-#endif
- stw %r7,MTX_OLDCPL(%r3) # save old ipl
- lwz %r0,20(%r1) # load return address
- mtlr %r0
- addi %r1,%r1,16 # restore stack
- blr
-
-#ifdef DIAGNOSTIC
-.L_mutex_selflocked:
- mr %r5, %r3
- lis %r3,.L_paniclocked@ha
- la %r3,.L_paniclocked@l(%r3)
- bl panic
-.L_paniclocked:
- .string "mtx_enter: recursed %x %x\n"
-#endif
-
-
-ENTRY(mtx_enter_try)
- stwu %r1,-16(%r1) # reserve stack
- mflr %r0
- stw %r0,20(%r1) # save return address
- stw %r3, 12(%r1)
- lwz %r3,MTX_WANTIPL(%r3) # load new ipl
- bl _C_LABEL(splraise)
- mr %r7, %r3
- GET_CPUINFO(%r4)
- lwz %r3,12(%r1)
- li %r5,MTX_OWNER # load offset constant
- lwarx %r6,%r5,%r3 # load reserve owner
- cmpwi 0,%r6,0 # test owner == 0
- beq+ 0,.L_mutex_try_free # if owner == 0 branch free
-.L_mutex_try_locked:
-#ifdef DIAGNOSTIC
- cmpl 0,%r4,%r6
- beq- .L_mutex_try_selflocked
-#endif
- stw %r3,12(%r1) # save mtx during lcsplx
- la %r4,12(%r1)
- stwcx. %r3,0,%r4 # unreserve owner
- mr %r3,%r7 # move old cpl to arg0
- bl _C_LABEL(lcsplx) # call splx on old cpl
-
- lwz %r0,20(%r1) # load return address
- mtlr %r0
- addi %r1,%r1,16 # restore stack
- li %r3,0 # return zero
- blr
-
-.L_mutex_try_free:
- stwcx. %r4,%r5,%r3 # old owner was 0 cond store
- bne- .L_mutex_try_locked # branch if reserve cancelled
- isync # memory barrier
-#ifdef DIAGNOSTIC
- lwz %r6,CI_MUTEX_LEVEL(%r4)
- addi %r6,%r6,1 # curpcu->ci_mutex_level++
- stw %r6,CI_MUTEX_LEVEL(%r4)
-#endif
- stw %r7,MTX_OLDCPL(%r3) # save old ipl
- lwz %r0,20(%r1) # load return address
- mtlr %r0
- addi %r1,%r1,16 # restore stack
- li %r3,1 # return nonzero
- blr
-
-#ifdef DIAGNOSTIC
-.L_mutex_try_selflocked:
- mr %r5, %r3
- lis %r3,.L_panictrylocked@ha
- la %r3,.L_panictrylocked@l(%r3)
- bl panic
-.L_panictrylocked:
- .string "mtx_enter_try: recursed %x %x\n"
-#endif
-
-
-ENTRY(mtx_leave)
-#ifdef DIAGNOSTIC
- lwz %r6,MTX_OWNER(%r3)
- cmpwi 0,%r6,0 # test owner == 0
-
- beq- .L_mutex_notlocked
-#endif
- li %r4,0
- lwz %r5,MTX_OLDCPL(%r3)
- stw %r4,MTX_OLDCPL(%r3)
- sync # memory barrier
- stw %r4,MTX_OWNER(%r3)
- GET_CPUINFO(%r4)
-#ifdef DIAGNOSTIC
- lwz %r6,CI_MUTEX_LEVEL(%r4)
- addi %r6,%r6,-1 # curpcu->ci_mutex_level--
- stw %r6,CI_MUTEX_LEVEL(%r4)
-#endif
- mr %r3,%r5
- lwz %r5,CI_CPL(%r4)
- cmpl 0,%r3,%r5
- beq 1f
- b _C_LABEL(lcsplx)
-1:
- blr
-
-#ifdef DIAGNOSTIC
-.L_mutex_notlocked:
- GET_CPUINFO(%r4)
- mr %r5, %r3
- lis %r3,.L_panicnotlocked@ha
- la %r3,.L_panicnotlocked@l(%r3)
- bl panic
-.L_panicnotlocked:
- .string "mtx_leave: not locked %x %x\n"
-#endif
diff --git a/sys/arch/powerpc/powerpc/mutex.c b/sys/arch/powerpc/powerpc/mutex.c
new file mode 100644
index 00000000000..dd89ae0747f
--- /dev/null
+++ b/sys/arch/powerpc/powerpc/mutex.c
@@ -0,0 +1,150 @@
+/* $OpenBSD: mutex.c,v 1.1 2015/08/14 06:14:19 dlg Exp $ */
+
+/*
+ * Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/mutex.h>
+#include <sys/systm.h>
+#include <sys/atomic.h>
+
+#include <machine/intr.h>
+#include <machine/lock.h>
+
+#include <ddb/db_output.h>
+
+void
+__mtx_init(struct mutex *mtx, int ipl)
+{
+ mtx->mtx_owner = NULL;
+ mtx->mtx_wantipl = ipl;
+ mtx->mtx_oldipl = IPL_NONE;
+}
+
+#ifdef MULTIPROCESSOR
+#if defined(MP_LOCKDEBUG)
+#ifndef DDB
+#error "MP_LOCKDEBUG requires DDB"
+#endif
+
+/* CPU-dependent timing, needs this to be settable from ddb. */
+extern int __mp_lock_spinout;
+#endif
+
+void
+mtx_enter(struct mutex *mtx)
+{
+#if defined(MP_LOCKDEBUG)
+ int ticks = __mp_lock_spinout;
+#endif
+
+ while (mtx_enter_try(mtx) == 0) {
+ SPINLOCK_SPIN_HOOK;
+
+#if defined(MP_LOCKDEBUG)
+ if (--ticks == 0) {
+ db_printf("%s: %p lock spun out", __func__, mtx);
+ Debugger();
+ }
+#endif
+ }
+}
+
+int
+mtx_enter_try(struct mutex *mtx)
+{
+ struct cpu_info *owner, *ci = curcpu();
+ int s;
+
+ if (mtx->mtx_wantipl != IPL_NONE)
+ s = splraise(mtx->mtx_wantipl);
+
+ owner = atomic_cas_ptr(&mtx->mtx_owner, NULL, ci);
+#ifdef DIAGNOSTIC
+ if (__predict_false(owner == ci))
+ panic("mtx %p: locking against myself", mtx);
+#endif
+ if (owner == NULL) {
+ if (mtx->mtx_wantipl != IPL_NONE)
+ mtx->mtx_oldipl = s;
+#ifdef DIAGNOSTIC
+ ci->ci_mutex_level++;
+#endif
+ membar_enter();
+ return (1);
+ }
+
+ if (mtx->mtx_wantipl != IPL_NONE)
+ splx(s);
+
+ return (0);
+}
+#else
+void
+mtx_enter(struct mutex *mtx)
+{
+ struct cpu_info *ci = curcpu();
+
+#ifdef DIAGNOSTIC
+ if (__predict_false(mtx->mtx_owner == ci))
+ panic("mtx %p: locking against myself", mtx);
+#endif
+ if (mtx->mtx_wantipl != IPL_NONE)
+ mtx->mtx_oldipl = splraise(mtx->mtx_wantipl);
+
+ mtx->mtx_owner = ci;
+
+#ifdef DIAGNOSTIC
+ ci->ci_mutex_level++;
+#endif
+}
+
+int
+mtx_enter_try(struct mutex *mtx)
+{
+ mtx_enter(mtx);
+ return (1);
+}
+#endif
+
+void
+mtx_leave(struct mutex *mtx)
+{
+ int s;
+
+ MUTEX_ASSERT_LOCKED(mtx);
+
+#ifdef MULTIPROCESSOR
+ membar_exit();
+#endif
+#ifdef DIAGNOSTIC
+ curcpu()->ci_mutex_level--;
+#endif
+
+ s = mtx->mtx_oldipl;
+ mtx->mtx_owner = NULL;
+ if (mtx->mtx_wantipl != IPL_NONE)
+ splx(s);
+}