diff options
author | Visa Hankala <visa@cvs.openbsd.org> | 2017-10-17 14:25:36 +0000 |
---|---|---|
committer | Visa Hankala <visa@cvs.openbsd.org> | 2017-10-17 14:25:36 +0000 |
commit | 1736274fb9f19f34d92aa10612489925834772d7 (patch) | |
tree | 5c6e47d74a882ae412fb1b30c94e9a0994d70eac /sys | |
parent | bffb3558829269f9819254da4202352807d3580a (diff) |
Add a machine-independent implementation for the mplock.
This reduces code duplication and makes it easier to instrument
lock primitives.
The MI mplock uses the ticket lock code that has been in use
on amd64, i386 and sparc64. These are the architectures that now
switch to the MI code.
The lock_machdep.c files are unhooked from the build but not
removed yet, in case something goes wrong.
OK mpi@, kettenis@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/amd64/conf/files.amd64 | 3 | ||||
-rw-r--r-- | sys/arch/amd64/include/cpu.h | 3 | ||||
-rw-r--r-- | sys/arch/amd64/include/mplock.h | 79 | ||||
-rw-r--r-- | sys/arch/i386/conf/files.i386 | 3 | ||||
-rw-r--r-- | sys/arch/i386/include/cpu.h | 4 | ||||
-rw-r--r-- | sys/arch/i386/include/mplock.h | 71 | ||||
-rw-r--r-- | sys/arch/sparc64/conf/files.sparc64 | 3 | ||||
-rw-r--r-- | sys/arch/sparc64/include/mplock.h | 49 | ||||
-rw-r--r-- | sys/kern/kern_lock.c | 182 | ||||
-rw-r--r-- | sys/sys/mplock.h | 65 |
10 files changed, 242 insertions, 220 deletions
diff --git a/sys/arch/amd64/conf/files.amd64 b/sys/arch/amd64/conf/files.amd64 index 546ca9c9f6b..eebe6349f29 100644 --- a/sys/arch/amd64/conf/files.amd64 +++ b/sys/arch/amd64/conf/files.amd64 @@ -1,4 +1,4 @@ -# $OpenBSD: files.amd64,v 1.90 2017/10/06 13:33:53 mikeb Exp $ +# $OpenBSD: files.amd64,v 1.91 2017/10/17 14:25:35 visa Exp $ maxpartitions 16 maxusers 2 16 128 @@ -32,7 +32,6 @@ file arch/amd64/amd64/mutex.S file arch/amd64/amd64/vector.S file arch/amd64/amd64/copy.S file arch/amd64/amd64/spl.S -file arch/amd64/amd64/lock_machdep.c multiprocessor file arch/amd64/amd64/intr.c file arch/amd64/amd64/bus_space.c diff --git a/sys/arch/amd64/include/cpu.h b/sys/arch/amd64/include/cpu.h index 9f7926d69b5..3c9390272eb 100644 --- a/sys/arch/amd64/include/cpu.h +++ b/sys/arch/amd64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.115 2017/10/06 13:33:53 mikeb Exp $ */ +/* $OpenBSD: cpu.h,v 1.116 2017/10/17 14:25:35 visa Exp $ */ /* $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $ */ /*- @@ -280,6 +280,7 @@ extern struct cpu_info cpu_info_primary; #endif /* MULTIPROCESSOR */ +#include <machine/cpufunc.h> #include <machine/psl.h> #endif /* _KERNEL */ diff --git a/sys/arch/amd64/include/mplock.h b/sys/arch/amd64/include/mplock.h index 2caf7439f32..a215816bccd 100644 --- a/sys/arch/amd64/include/mplock.h +++ b/sys/arch/amd64/include/mplock.h @@ -1,83 +1,10 @@ -/* $OpenBSD: mplock.h,v 1.4 2017/04/20 13:20:17 visa Exp $ */ +/* $OpenBSD: mplock.h,v 1.5 2017/10/17 14:25:35 visa Exp $ */ -/* - * Copyright (c) 2004 Niklas Hallqvist. 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. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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. - */ +/* public domain */ #ifndef _MACHINE_MPLOCK_H_ #define _MACHINE_MPLOCK_H_ -#include <sys/_lock.h> - -struct __mp_lock_cpu { - u_int mplc_ticket; - u_int mplc_depth; -}; - -struct __mp_lock { - struct __mp_lock_cpu mpl_cpus[MAXCPUS]; - volatile u_int mpl_ticket; - u_int mpl_users; -#ifdef WITNESS - struct lock_object mpl_lock_obj; -#endif -}; - -#ifndef _LOCORE - -void ___mp_lock_init(struct __mp_lock *); -void ___mp_lock(struct __mp_lock * LOCK_FL_VARS); -void ___mp_unlock(struct __mp_lock * LOCK_FL_VARS); -int ___mp_release_all(struct __mp_lock * LOCK_FL_VARS); -int ___mp_release_all_but_one(struct __mp_lock * LOCK_FL_VARS); -void ___mp_acquire_count(struct __mp_lock *, int LOCK_FL_VARS); -int __mp_lock_held(struct __mp_lock *); - -#ifdef WITNESS - -void _mp_lock_init(struct __mp_lock *, struct lock_type *); - -#define __mp_lock_init(mpl) do { \ - static struct lock_type __lock_type = { .lt_name = #mpl }; \ - _mp_lock_init((mpl), &__lock_type); \ -} while (0) - -#else /* WITNESS */ - -#define __mp_lock_init ___mp_lock_init - -#endif /* WITNESS */ - -#define __mp_lock(mpl) ___mp_lock((mpl) LOCK_FILE_LINE) -#define __mp_unlock(mpl) ___mp_unlock((mpl) LOCK_FILE_LINE) - -#define __mp_release_all(mpl) \ - ___mp_release_all((mpl) LOCK_FILE_LINE) -#define __mp_release_all_but_one(mpl) \ - ___mp_release_all_but_one((mpl) LOCK_FILE_LINE) -#define __mp_acquire_count(mpl, count) \ - ___mp_acquire_count((mpl), (count) LOCK_FILE_LINE) - -#endif +#define __USE_MI_MPLOCK #endif /* !_MACHINE_MPLOCK_H */ diff --git a/sys/arch/i386/conf/files.i386 b/sys/arch/i386/conf/files.i386 index 5cc8724bb97..d456228f6ae 100644 --- a/sys/arch/i386/conf/files.i386 +++ b/sys/arch/i386/conf/files.i386 @@ -1,4 +1,4 @@ -# $OpenBSD: files.i386,v 1.234 2017/08/03 06:35:24 fcambus Exp $ +# $OpenBSD: files.i386,v 1.235 2017/10/17 14:25:35 visa Exp $ # # new style config file for i386 architecture # @@ -46,7 +46,6 @@ file arch/i386/i386/dkcsum.c bios file dev/cninit.c file arch/i386/i386/mptramp.s multiprocessor file arch/i386/i386/mp_setperf.c multiprocessor -file arch/i386/i386/lock_machdep.c file arch/i386/i386/ipifuncs.c multiprocessor file arch/i386/i386/db_mp.c multiprocessor & ddb file arch/i386/i386/wscons_machdep.c wsdisplay diff --git a/sys/arch/i386/include/cpu.h b/sys/arch/i386/include/cpu.h index 2b0ff5aa9ce..e89d43951c0 100644 --- a/sys/arch/i386/include/cpu.h +++ b/sys/arch/i386/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.157 2017/08/17 19:44:27 tedu Exp $ */ +/* $OpenBSD: cpu.h,v 1.158 2017/10/17 14:25:35 visa Exp $ */ /* $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $ */ /*- @@ -283,6 +283,8 @@ void cpu_unidle(struct cpu_info *); #endif +#include <machine/cpufunc.h> + #define aston(p) ((p)->p_md.md_astpending = 1) #define curpcb curcpu()->ci_curpcb diff --git a/sys/arch/i386/include/mplock.h b/sys/arch/i386/include/mplock.h index cd166dde690..57d665d7884 100644 --- a/sys/arch/i386/include/mplock.h +++ b/sys/arch/i386/include/mplock.h @@ -1,73 +1,10 @@ -/* - * Copyright (c) 2007 Artur Grabowski <art@openbsd.org> - * - * 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. - */ +/* $OpenBSD: mplock.h,v 1.4 2017/10/17 14:25:35 visa Exp $ */ + +/* public domain */ #ifndef _MACHINE_MPLOCK_H_ #define _MACHINE_MPLOCK_H_ -#include <sys/_lock.h> - -struct __mp_lock_cpu { - u_int mplc_ticket; - u_int mplc_depth; -}; - -struct __mp_lock { - struct __mp_lock_cpu mpl_cpus[MAXCPUS]; - volatile u_int mpl_ticket; - u_int mpl_users; -#ifdef WITNESS - struct lock_object mpl_lock_obj; -#endif -}; - -#ifndef _LOCORE - -void ___mp_lock_init(struct __mp_lock *); -void ___mp_lock(struct __mp_lock * LOCK_FL_VARS); -void ___mp_unlock(struct __mp_lock * LOCK_FL_VARS); -int ___mp_release_all(struct __mp_lock * LOCK_FL_VARS); -int ___mp_release_all_but_one(struct __mp_lock * LOCK_FL_VARS); -void ___mp_acquire_count(struct __mp_lock *, int LOCK_FL_VARS); -int __mp_lock_held(struct __mp_lock *); - -#ifdef WITNESS - -void _mp_lock_init(struct __mp_lock *, struct lock_type *); - -#define __mp_lock_init(mpl) do { \ - static struct lock_type __lock_type = { .lt_name = #mpl }; \ - _mp_lock_init((mpl), &__lock_type); \ -} while (0) - -#else /* WITNESS */ - -#define __mp_lock_init ___mp_lock_init - -#endif /* WITNESS */ - -#define __mp_lock(mpl) ___mp_lock((mpl) LOCK_FILE_LINE) -#define __mp_unlock(mpl) ___mp_unlock((mpl) LOCK_FILE_LINE) - -#define __mp_release_all(mpl) \ - ___mp_release_all((mpl) LOCK_FILE_LINE) -#define __mp_release_all_but_one(mpl) \ - ___mp_release_all_but_one((mpl) LOCK_FILE_LINE) -#define __mp_acquire_count(mpl, count) \ - ___mp_acquire_count((mpl), (count) LOCK_FILE_LINE) - -#endif +#define __USE_MI_MPLOCK #endif /* !_MACHINE_MPLOCK_H */ diff --git a/sys/arch/sparc64/conf/files.sparc64 b/sys/arch/sparc64/conf/files.sparc64 index 28b8e112c4c..e97e89aa7a9 100644 --- a/sys/arch/sparc64/conf/files.sparc64 +++ b/sys/arch/sparc64/conf/files.sparc64 @@ -1,4 +1,4 @@ -# $OpenBSD: files.sparc64,v 1.148 2016/01/08 15:54:13 jcs Exp $ +# $OpenBSD: files.sparc64,v 1.149 2017/10/17 14:25:35 visa Exp $ # $NetBSD: files.sparc64,v 1.50 2001/08/10 20:53:50 eeh Exp $ # maxpartitions must be first item in files.${ARCH} @@ -326,7 +326,6 @@ file arch/sparc64/sparc64/ipifuncs.c multiprocessor file arch/sparc64/sparc64/kgdb_machdep.c kgdb # sparc64/sparc64/locore.s is handled specially in the makefile, # because it must come first in the "ld" command line. -file arch/sparc64/sparc64/lock_machdep.c multiprocessor file arch/sparc64/sparc64/machdep.c file arch/sparc64/sparc64/mdesc.c sun4v file arch/sparc64/sparc64/mem.c diff --git a/sys/arch/sparc64/include/mplock.h b/sys/arch/sparc64/include/mplock.h index 7b7d9cc7a59..57d665d7884 100644 --- a/sys/arch/sparc64/include/mplock.h +++ b/sys/arch/sparc64/include/mplock.h @@ -1,53 +1,10 @@ -/* $OpenBSD: mplock.h,v 1.3 2014/03/14 01:20:44 dlg Exp $ */ +/* $OpenBSD: mplock.h,v 1.4 2017/10/17 14:25:35 visa Exp $ */ -/* - * Copyright (c) 2004 Niklas Hallqvist. 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. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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. - */ +/* public domain */ #ifndef _MACHINE_MPLOCK_H_ #define _MACHINE_MPLOCK_H_ -struct __mp_lock_cpu { - volatile u_int mplc_ticket; - volatile u_int mplc_depth; -}; - -struct __mp_lock { - struct __mp_lock_cpu mpl_cpus[MAXCPUS]; - volatile u_int mpl_ticket; - volatile u_int mpl_users; -}; - -#ifndef _LOCORE - -void __mp_lock_init(struct __mp_lock *); -void __mp_lock(struct __mp_lock *); -void __mp_unlock(struct __mp_lock *); -int __mp_release_all(struct __mp_lock *); -int __mp_release_all_but_one(struct __mp_lock *); -void __mp_acquire_count(struct __mp_lock *, int); -int __mp_lock_held(struct __mp_lock *); - -#endif +#define __USE_MI_MPLOCK #endif /* !_MACHINE_MPLOCK_H */ diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c index 3bda382d569..3b6adb16c93 100644 --- a/sys/kern/kern_lock.c +++ b/sys/kern/kern_lock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_lock.c,v 1.50 2017/10/09 08:16:13 mpi Exp $ */ +/* $OpenBSD: kern_lock.c,v 1.51 2017/10/17 14:25:35 visa Exp $ */ /* * Copyright (c) 1995 @@ -36,24 +36,33 @@ */ #include <sys/param.h> -#include <sys/lock.h> #include <sys/systm.h> #include <sys/sched.h> +#include <sys/atomic.h> #include <sys/witness.h> +#include <ddb/db_output.h> + #ifdef MP_LOCKDEBUG +#ifndef DDB +#error "MP_LOCKDEBUG requires DDB" +#endif + /* CPU-dependent timing, this needs to be settable from ddb. */ int __mp_lock_spinout = 200000000; +#endif /* MP_LOCKDEBUG */ + +#if defined(MULTIPROCESSOR) || defined(WITNESS) +struct __mp_lock kernel_lock; #endif -#if defined(MULTIPROCESSOR) +#ifdef MULTIPROCESSOR + /* * Functions for manipulating the kernel_lock. We put them here * so that they show up in profiles. */ -struct __mp_lock kernel_lock; - void _kernel_lock_init(void) { @@ -90,10 +99,35 @@ _kernel_lock_held(void) return (__mp_lock_held(&kernel_lock)); } -#ifdef WITNESS +#ifdef __USE_MI_MPLOCK + +/* Ticket lock implementation */ +/* + * Copyright (c) 2014 David Gwynne <dlg@openbsd.org> + * + * 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 <machine/cpu.h> + void -_mp_lock_init(struct __mp_lock *mpl, struct lock_type *type) +___mp_lock_init(struct __mp_lock *mpl, struct lock_type *type) { + memset(mpl->mpl_cpus, 0, sizeof(mpl->mpl_cpus)); + mpl->mpl_users = 0; + mpl->mpl_ticket = 1; + +#ifdef WITNESS mpl->mpl_lock_obj.lo_name = type->lt_name; mpl->mpl_lock_obj.lo_type = type; if (mpl == &kernel_lock) @@ -103,9 +137,139 @@ _mp_lock_init(struct __mp_lock *mpl, struct lock_type *type) mpl->mpl_lock_obj.lo_flags = LO_WITNESS | LO_INITIALIZED | LO_RECURSABLE | (LO_CLASS_SCHED_LOCK << LO_CLASSSHIFT); WITNESS_INIT(&mpl->mpl_lock_obj, type); +#endif +} + +static __inline void +__mp_lock_spin(struct __mp_lock *mpl, u_int me) +{ +#ifndef MP_LOCKDEBUG + while (mpl->mpl_ticket != me) + CPU_BUSY_CYCLE(); +#else + int nticks = __mp_lock_spinout; + + while (mpl->mpl_ticket != me) { + CPU_BUSY_CYCLE(); + + if (--nticks <= 0) { + db_printf("__mp_lock(%p): lock spun out", mpl); + db_enter(); + nticks = __mp_lock_spinout; + } + } +#endif +} + +void +___mp_lock(struct __mp_lock *mpl LOCK_FL_VARS) +{ + struct __mp_lock_cpu *cpu = &mpl->mpl_cpus[cpu_number()]; + unsigned long s; + +#ifdef WITNESS + if (!__mp_lock_held(mpl)) + WITNESS_CHECKORDER(&mpl->mpl_lock_obj, + LOP_EXCLUSIVE | LOP_NEWORDER, file, line, NULL); +#endif + + s = intr_disable(); + if (cpu->mplc_depth++ == 0) + cpu->mplc_ticket = atomic_inc_int_nv(&mpl->mpl_users); + intr_restore(s); + + __mp_lock_spin(mpl, cpu->mplc_ticket); + membar_enter_after_atomic(); + + WITNESS_LOCK(&mpl->mpl_lock_obj, LOP_EXCLUSIVE, file, line); +} + +void +___mp_unlock(struct __mp_lock *mpl LOCK_FL_VARS) +{ + struct __mp_lock_cpu *cpu = &mpl->mpl_cpus[cpu_number()]; + unsigned long s; + +#ifdef MP_LOCKDEBUG + if (!__mp_lock_held(mpl)) { + db_printf("__mp_unlock(%p): not held lock\n", mpl); + db_enter(); + } +#endif + + WITNESS_UNLOCK(&mpl->mpl_lock_obj, LOP_EXCLUSIVE, file, line); + + s = intr_disable(); + if (--cpu->mplc_depth == 0) { + membar_exit(); + mpl->mpl_ticket++; + } + intr_restore(s); +} + +int +___mp_release_all(struct __mp_lock *mpl LOCK_FL_VARS) +{ + struct __mp_lock_cpu *cpu = &mpl->mpl_cpus[cpu_number()]; + unsigned long s; + int rv; +#ifdef WITNESS + int i; +#endif + + s = intr_disable(); + rv = cpu->mplc_depth; +#ifdef WITNESS + for (i = 0; i < rv; i++) + WITNESS_UNLOCK(&mpl->mpl_lock_obj, LOP_EXCLUSIVE, file, line); +#endif + cpu->mplc_depth = 0; + membar_exit(); + mpl->mpl_ticket++; + intr_restore(s); + + return (rv); +} + +int +___mp_release_all_but_one(struct __mp_lock *mpl LOCK_FL_VARS) +{ + struct __mp_lock_cpu *cpu = &mpl->mpl_cpus[cpu_number()]; + int rv = cpu->mplc_depth - 1; +#ifdef WITNESS + int i; + + for (i = 0; i < rv; i++) + WITNESS_UNLOCK(&mpl->mpl_lock_obj, LOP_EXCLUSIVE, file, line); +#endif - ___mp_lock_init(mpl); +#ifdef MP_LOCKDEBUG + if (!__mp_lock_held(mpl)) { + db_printf("__mp_release_all_but_one(%p): not held lock\n", mpl); + db_enter(); + } +#endif + + cpu->mplc_depth = 1; + + return (rv); } -#endif /* WITNESS */ + +void +___mp_acquire_count(struct __mp_lock *mpl, int count LOCK_FL_VARS) +{ + while (count--) + ___mp_lock(mpl LOCK_FL_ARGS); +} + +int +__mp_lock_held(struct __mp_lock *mpl) +{ + struct __mp_lock_cpu *cpu = &mpl->mpl_cpus[cpu_number()]; + + return (cpu->mplc_ticket == mpl->mpl_ticket && cpu->mplc_depth > 0); +} + +#endif /* __USE_MI_MPLOCK */ #endif /* MULTIPROCESSOR */ diff --git a/sys/sys/mplock.h b/sys/sys/mplock.h index 92dc8066bdf..a1a0623573e 100644 --- a/sys/sys/mplock.h +++ b/sys/sys/mplock.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mplock.h,v 1.9 2007/11/26 17:15:29 art Exp $ */ +/* $OpenBSD: mplock.h,v 1.10 2017/10/17 14:25:35 visa Exp $ */ /* * Copyright (c) 2004 Niklas Hallqvist. All rights reserved. @@ -27,21 +27,58 @@ #ifndef _MPLOCK_H_ #define _MPLOCK_H_ -#ifdef notyet -/* - * Enable the prototypes once the architectures stop playing around - * with inlines. - */ -void __mp_lock_init(struct __mp_lock *); -void __mp_lock(struct __mp_lock *); -void __mp_unlock(struct __mp_lock *); -int __mp_release_all(struct __mp_lock *); -int __mp_release_all_but_one(struct __mp_lock *); -void __mp_acquire_count(struct __mp_lock *, int); -int __mp_lock_held(struct __mp_lock *); +#include <machine/mplock.h> + +#ifdef __USE_MI_MPLOCK + +#include <sys/_lock.h> + +struct __mp_lock_cpu { + u_int mplc_ticket; + u_int mplc_depth; +}; + +struct __mp_lock { + struct __mp_lock_cpu mpl_cpus[MAXCPUS]; + volatile u_int mpl_ticket; + u_int mpl_users; +#ifdef WITNESS + struct lock_object mpl_lock_obj; #endif +}; -#include <machine/mplock.h> +void ___mp_lock_init(struct __mp_lock *, struct lock_type *); +void ___mp_lock(struct __mp_lock * LOCK_FL_VARS); +void ___mp_unlock(struct __mp_lock * LOCK_FL_VARS); +int ___mp_release_all(struct __mp_lock * LOCK_FL_VARS); +int ___mp_release_all_but_one(struct __mp_lock * LOCK_FL_VARS); +void ___mp_acquire_count(struct __mp_lock *, int LOCK_FL_VARS); +int __mp_lock_held(struct __mp_lock *); + +#ifdef WITNESS + +#define __mp_lock_init(mpl) do { \ + static struct lock_type __lock_type = { .lt_name = #mpl }; \ + ___mp_lock_init((mpl), &__lock_type); \ +} while (0) + +#else /* WITNESS */ + +#define __mp_lock_init(mpl) ___mp_lock_init((mpl), NULL) + +#endif /* WITNESS */ + +#define __mp_lock(mpl) ___mp_lock((mpl) LOCK_FILE_LINE) +#define __mp_unlock(mpl) ___mp_unlock((mpl) LOCK_FILE_LINE) + +#define __mp_release_all(mpl) \ + ___mp_release_all((mpl) LOCK_FILE_LINE) +#define __mp_release_all_but_one(mpl) \ + ___mp_release_all_but_one((mpl) LOCK_FILE_LINE) +#define __mp_acquire_count(mpl, count) \ + ___mp_acquire_count((mpl), (count) LOCK_FILE_LINE) + +#endif /* __USE_MI_MPLOCK */ extern struct __mp_lock kernel_lock; |