Here's a diff to switch hppa to the MI mutex implementation. I'm looking for testers, as I don't own such hardware.
Note that our MI mutex implementation relies on atomic_cas_ptr(9). On hppa all the calls to this function are serialized on a single lock. I don't believe it will introduce contention at this point since the KERNEL_LOCK() is still the problem. However if it becomes a bottleneck we could use multiple locks in a small hash table. Index: arch/hppa/conf/files.hppa =================================================================== RCS file: /cvs/src/sys/arch/hppa/conf/files.hppa,v retrieving revision 1.97 diff -u -p -r1.97 files.hppa --- arch/hppa/conf/files.hppa 5 Jun 2017 18:59:07 -0000 1.97 +++ arch/hppa/conf/files.hppa 12 Feb 2018 10:08:57 -0000 @@ -298,7 +298,6 @@ file arch/hppa/hppa/fpu.c file arch/hppa/hppa/ipi.c multiprocessor file arch/hppa/hppa/lock_machdep.c multiprocessor file arch/hppa/hppa/machdep.c -file arch/hppa/hppa/mutex.c file arch/hppa/hppa/pmap.c file arch/hppa/hppa/process_machdep.c file arch/hppa/hppa/sys_machdep.c Index: arch/hppa/hppa/genassym.cf =================================================================== RCS file: /cvs/src/sys/arch/hppa/hppa/genassym.cf,v retrieving revision 1.47 diff -u -p -r1.47 genassym.cf --- arch/hppa/hppa/genassym.cf 9 Feb 2015 08:20:13 -0000 1.47 +++ arch/hppa/hppa/genassym.cf 12 Feb 2018 10:15:56 -0000 @@ -45,7 +45,7 @@ include <uvm/uvm_extern.h> include <machine/cpu.h> include <machine/frame.h> include <machine/iomod.h> -include <machine/mutex.h> +include <sys/mutex.h> include <machine/pmap.h> include <machine/psl.h> include <machine/pte.h> Index: arch/hppa/hppa/ipi.c =================================================================== RCS file: /cvs/src/sys/arch/hppa/hppa/ipi.c,v retrieving revision 1.5 diff -u -p -r1.5 ipi.c --- arch/hppa/hppa/ipi.c 8 Sep 2017 05:36:51 -0000 1.5 +++ arch/hppa/hppa/ipi.c 12 Feb 2018 10:16:01 -0000 @@ -25,7 +25,7 @@ #include <machine/fpu.h> #include <machine/iomod.h> #include <machine/intr.h> -#include <machine/mutex.h> +#include <sys/mutex.h> #include <machine/reg.h> void hppa_ipi_nop(void); Index: arch/hppa/hppa/mutex.c =================================================================== RCS file: arch/hppa/hppa/mutex.c diff -N arch/hppa/hppa/mutex.c --- arch/hppa/hppa/mutex.c 20 Apr 2017 13:57:29 -0000 1.16 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,156 +0,0 @@ -/* $OpenBSD: mutex.c,v 1.16 2017/04/20 13:57:29 visa Exp $ */ - -/* - * Copyright (c) 2004 Artur Grabowski <[email protected]> - * 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 <ddb/db_output.h> - -int __mtx_enter_try(struct mutex *); - -#ifdef MULTIPROCESSOR -/* Note: lock must be 16-byte aligned. */ -#define __mtx_lock(mtx) ((int *)(((vaddr_t)mtx->mtx_lock + 0xf) & ~0xf)) -#endif - -void -__mtx_init(struct mutex *mtx, int wantipl) -{ -#ifdef MULTIPROCESSOR - mtx->mtx_lock[0] = 1; - mtx->mtx_lock[1] = 1; - mtx->mtx_lock[2] = 1; - mtx->mtx_lock[3] = 1; -#endif - mtx->mtx_wantipl = wantipl; - mtx->mtx_oldipl = IPL_NONE; - mtx->mtx_owner = NULL; -} - -#ifdef MULTIPROCESSOR -void -__mtx_enter(struct mutex *mtx) -{ - while (__mtx_enter_try(mtx) == 0) - ; -} - -int -__mtx_enter_try(struct mutex *mtx) -{ - struct cpu_info *ci = curcpu(); - volatile int *lock = __mtx_lock(mtx); - int ret; - int s; - - if (mtx->mtx_wantipl != IPL_NONE) - s = splraise(mtx->mtx_wantipl); - -#ifdef DIAGNOSTIC - if (__predict_false(mtx->mtx_owner == ci)) - panic("mtx %p: locking against myself", mtx); -#endif - - asm volatile ( - "ldcws 0(%2), %0" - : "=&r" (ret), "+m" (lock) - : "r" (lock) - ); - - if (ret) { - membar_enter(); - mtx->mtx_owner = ci; - 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) -{ -#ifdef MULTIPROCESSOR - volatile int *lock = __mtx_lock(mtx); -#endif - int s; - - MUTEX_ASSERT_LOCKED(mtx); - -#ifdef DIAGNOSTIC - curcpu()->ci_mutex_level--; -#endif - s = mtx->mtx_oldipl; - mtx->mtx_owner = NULL; -#ifdef MULTIPROCESSOR - membar_exit(); - *lock = 1; -#endif - - if (mtx->mtx_wantipl != IPL_NONE) - splx(s); -} Index: arch/hppa/include/cpu.h =================================================================== RCS file: /cvs/src/sys/arch/hppa/include/cpu.h,v retrieving revision 1.90 diff -u -p -r1.90 cpu.h --- arch/hppa/include/cpu.h 18 May 2017 15:41:59 -0000 1.90 +++ arch/hppa/include/cpu.h 12 Feb 2018 10:16:09 -0000 @@ -70,7 +70,7 @@ #include <sys/queue.h> #include <sys/sched.h> -#include <machine/mutex.h> +#include <sys/mutex.h> /* * Note that the alignment of ci_trap_save is important since we want to keep Index: arch/hppa/include/mutex.h =================================================================== RCS file: /cvs/src/sys/arch/hppa/include/mutex.h,v retrieving revision 1.9 diff -u -p -r1.9 mutex.h --- arch/hppa/include/mutex.h 13 Jan 2018 15:18:11 -0000 1.9 +++ arch/hppa/include/mutex.h 12 Feb 2018 10:11:34 -0000 @@ -1,93 +1,3 @@ /* $OpenBSD: mutex.h,v 1.9 2018/01/13 15:18:11 mpi Exp $ */ -/* - * Copyright (c) 2004 Artur Grabowski <[email protected]> - * 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. - */ - -#ifndef _MACHINE_MUTEX_H_ -#define _MACHINE_MUTEX_H_ - -#include <sys/_lock.h> - -#define MUTEX_UNLOCKED { 1, 1, 1, 1 } - -/* Note: mtx_lock must be 16-byte aligned. */ -struct mutex { -#ifdef MULTIPROCESSOR - volatile int mtx_lock[4]; -#endif - int mtx_wantipl; - int mtx_oldipl; - volatile void *mtx_owner; -#ifdef WITNESS - struct lock_object mtx_lock_obj; -#endif -}; - -/* - * To prevent lock ordering problems with the kernel lock, we need to - * make sure we block all interrupts that can grab the kernel lock. - * The simplest way to achieve this is to make sure mutexes always - * raise the interrupt priority level to the highest level that has - * interrupts that grab the kernel lock. - */ -#ifdef MULTIPROCESSOR -#define __MUTEX_IPL(ipl) \ - (((ipl) > IPL_NONE && (ipl) < IPL_MPFLOOR) ? IPL_MPFLOOR : (ipl)) -#ifdef WITNESS -#define MUTEX_INITIALIZER_FLAGS(ipl, name, flags) \ - { MUTEX_UNLOCKED, __MUTEX_IPL((ipl)), 0, NULL, \ - MTX_LO_INITIALIZER(name, flags) } -#else /* WITNESS */ -#define MUTEX_INITIALIZER_FLAGS(ipl, name, flags) \ - { MUTEX_UNLOCKED, __MUTEX_IPL((ipl)), 0, NULL } -#endif /* WITNESS */ -#else /* MULTIPROCESSOR */ -#define __MUTEX_IPL(ipl) (ipl) -#define MUTEX_INITIALIZER_FLAGS(ipl, name, flags) \ - { __MUTEX_IPL((ipl)), 0, NULL } -#endif /* MULTIPROCESSOR */ - -void __mtx_init(struct mutex *, int); -#define _mtx_init(mtx, ipl) __mtx_init((mtx), __MUTEX_IPL((ipl))) - -#ifdef DIAGNOSTIC -#define MUTEX_ASSERT_LOCKED(mtx) do { \ - if ((mtx)->mtx_owner != curcpu()) \ - panic("mutex %p not held in %s", (mtx), __func__); \ -} while (0) - -#define MUTEX_ASSERT_UNLOCKED(mtx) do { \ - if ((mtx)->mtx_owner == curcpu()) \ - panic("mutex %p held in %s", (mtx), __func__); \ -} while (0) -#else -#define MUTEX_ASSERT_LOCKED(mtx) do { } while (0) -#define MUTEX_ASSERT_UNLOCKED(mtx) do { } while (0) -#endif - -#define MUTEX_LOCK_OBJECT(mtx) (&(mtx)->mtx_lock_obj) -#define MUTEX_OLDIPL(mtx) (mtx)->mtx_oldipl - -#endif +#define __USE_MI_MUTEX
