From cd187a97da7d683c6a3e843cc98b3055da72c382 Mon Sep 17 00:00:00 2001 From: mpi Date: Wed, 20 Dec 2017 11:08:44 +0000 Subject: [PATCH] Switch x86 architectures to the common C mutex implementation. This is a step towards MI mutexes. ok kettenis@ --- sys/arch/amd64/amd64/mutex.c | 151 ++++++++++++++++++++++++++++++++ sys/arch/amd64/conf/files.amd64 | 4 +- sys/arch/i386/conf/files.i386 | 3 +- sys/arch/i386/i386/locore.s | 4 +- sys/arch/i386/i386/mutex.c | 151 ++++++++++++++++++++++++++++++++ 5 files changed, 307 insertions(+), 6 deletions(-) create mode 100644 sys/arch/amd64/amd64/mutex.c create mode 100644 sys/arch/i386/i386/mutex.c diff --git a/sys/arch/amd64/amd64/mutex.c b/sys/arch/amd64/amd64/mutex.c new file mode 100644 index 00000000000..9d42071a7aa --- /dev/null +++ b/sys/arch/amd64/amd64/mutex.c @@ -0,0 +1,151 @@ +/* $OpenBSD: mutex.c,v 1.1 2017/12/20 11:08:44 mpi Exp $ */ + +/* + * Copyright (c) 2004 Artur Grabowski + * 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 +#include +#include +#include + +#include + +#include + +void +__mtx_init(struct mutex *mtx, int wantipl) +{ + mtx->mtx_owner = NULL; + mtx->mtx_wantipl = wantipl; + mtx->mtx_oldipl = IPL_NONE; +} + +#ifdef MULTIPROCESSOR +#ifdef 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) +{ +#ifdef MP_LOCKDEBUG + int nticks = __mp_lock_spinout; +#endif + + while (__mtx_enter_try(mtx) == 0) { + CPU_BUSY_CYCLE(); + +#ifdef MP_LOCKDEBUG + if (--nticks == 0) { + db_printf("%s: %p lock spun out", __func__, mtx); + db_enter(); + nticks = __mp_lock_spinout; + } +#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) { + membar_enter_after_atomic(); + if (mtx->mtx_wantipl != IPL_NONE) + mtx->mtx_oldipl = s; +#ifdef DIAGNOSTIC + ci->ci_mutex_level++; +#endif + 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 DIAGNOSTIC + curcpu()->ci_mutex_level--; +#endif + + s = mtx->mtx_oldipl; +#ifdef MULTIPROCESSOR + membar_exit_before_atomic(); +#endif + mtx->mtx_owner = NULL; + if (mtx->mtx_wantipl != IPL_NONE) + splx(s); +} diff --git a/sys/arch/amd64/conf/files.amd64 b/sys/arch/amd64/conf/files.amd64 index eebe6349f29..5e742fae046 100644 --- a/sys/arch/amd64/conf/files.amd64 +++ b/sys/arch/amd64/conf/files.amd64 @@ -1,4 +1,4 @@ -# $OpenBSD: files.amd64,v 1.91 2017/10/17 14:25:35 visa Exp $ +# $OpenBSD: files.amd64,v 1.92 2017/12/20 11:08:44 mpi Exp $ maxpartitions 16 maxusers 2 16 128 @@ -28,7 +28,7 @@ file arch/amd64/amd64/fpu.c file arch/amd64/amd64/softintr.c file arch/amd64/amd64/i8259.c file arch/amd64/amd64/cacheinfo.c -file arch/amd64/amd64/mutex.S +file arch/amd64/amd64/mutex.c file arch/amd64/amd64/vector.S file arch/amd64/amd64/copy.S file arch/amd64/amd64/spl.S diff --git a/sys/arch/i386/conf/files.i386 b/sys/arch/i386/conf/files.i386 index d456228f6ae..76651889efe 100644 --- a/sys/arch/i386/conf/files.i386 +++ b/sys/arch/i386/conf/files.i386 @@ -1,4 +1,4 @@ -# $OpenBSD: files.i386,v 1.235 2017/10/17 14:25:35 visa Exp $ +# $OpenBSD: files.i386,v 1.236 2017/12/20 11:08:44 mpi Exp $ # # new style config file for i386 architecture # @@ -21,6 +21,7 @@ file arch/i386/i386/est.c !small_kernel file arch/i386/i386/gdt.c file arch/i386/i386/in_cksum.s file arch/i386/i386/machdep.c +file arch/i386/i386/mutex.c file arch/i386/i386/hibernate_machdep.c hibernate file arch/i386/i386/via.c file arch/i386/i386/locore.s diff --git a/sys/arch/i386/i386/locore.s b/sys/arch/i386/i386/locore.s index efc1787c35b..22c11c83606 100644 --- a/sys/arch/i386/i386/locore.s +++ b/sys/arch/i386/i386/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.180 2017/08/25 19:28:48 guenther Exp $ */ +/* $OpenBSD: locore.s,v 1.181 2017/12/20 11:08:44 mpi Exp $ */ /* $NetBSD: locore.s,v 1.145 1996/05/03 19:41:19 christos Exp $ */ /*- @@ -1319,8 +1319,6 @@ ENTRY(cpu_paenable) #include #endif -#include - .section .rodata .globl _C_LABEL(_stac) _C_LABEL(_stac): diff --git a/sys/arch/i386/i386/mutex.c b/sys/arch/i386/i386/mutex.c new file mode 100644 index 00000000000..9d42071a7aa --- /dev/null +++ b/sys/arch/i386/i386/mutex.c @@ -0,0 +1,151 @@ +/* $OpenBSD: mutex.c,v 1.1 2017/12/20 11:08:44 mpi Exp $ */ + +/* + * Copyright (c) 2004 Artur Grabowski + * 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 +#include +#include +#include + +#include + +#include + +void +__mtx_init(struct mutex *mtx, int wantipl) +{ + mtx->mtx_owner = NULL; + mtx->mtx_wantipl = wantipl; + mtx->mtx_oldipl = IPL_NONE; +} + +#ifdef MULTIPROCESSOR +#ifdef 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) +{ +#ifdef MP_LOCKDEBUG + int nticks = __mp_lock_spinout; +#endif + + while (__mtx_enter_try(mtx) == 0) { + CPU_BUSY_CYCLE(); + +#ifdef MP_LOCKDEBUG + if (--nticks == 0) { + db_printf("%s: %p lock spun out", __func__, mtx); + db_enter(); + nticks = __mp_lock_spinout; + } +#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) { + membar_enter_after_atomic(); + if (mtx->mtx_wantipl != IPL_NONE) + mtx->mtx_oldipl = s; +#ifdef DIAGNOSTIC + ci->ci_mutex_level++; +#endif + 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 DIAGNOSTIC + curcpu()->ci_mutex_level--; +#endif + + s = mtx->mtx_oldipl; +#ifdef MULTIPROCESSOR + membar_exit_before_atomic(); +#endif + mtx->mtx_owner = NULL; + if (mtx->mtx_wantipl != IPL_NONE) + splx(s); +} -- 2.20.1