diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2015-08-14 06:14:20 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2015-08-14 06:14:20 +0000 |
commit | 68704befa2a2cb39d5082887c61ae48a17125d96 (patch) | |
tree | 3db66de6fa463f2868f5edb2ce5f6f7aadf6c3a3 /sys/arch | |
parent | fc5e6e905c0592dfb3e47078a194cb111c88b040 (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.cf | 7 | ||||
-rw-r--r-- | sys/arch/powerpc/conf/files.powerpc | 4 | ||||
-rw-r--r-- | sys/arch/powerpc/include/lock.h | 4 | ||||
-rw-r--r-- | sys/arch/powerpc/include/mutex.h | 10 | ||||
-rw-r--r-- | sys/arch/powerpc/powerpc/lock_machdep.c | 4 | ||||
-rw-r--r-- | sys/arch/powerpc/powerpc/mutex.S | 182 | ||||
-rw-r--r-- | sys/arch/powerpc/powerpc/mutex.c | 150 |
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); +} |