From 0ff061fa90ba911165c0e8d0ef2b46680b6e6206 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Wed, 22 Jan 2014 11:01:16 +0000 Subject: 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 ipl to the highest level that has interrupts that grab the kernel lock. This will allow us to have "mpsafe" interrupt handlers at lower priority levels. No change for non-MULTIPROCESSOR kernels. tested by mpi@, landry@ ok mpi@, dlg@ --- sys/arch/powerpc/include/mutex.h | 26 ++++++++++++++++++++++++-- sys/arch/powerpc/powerpc/mutex.S | 4 ++-- 2 files changed, 26 insertions(+), 4 deletions(-) (limited to 'sys') diff --git a/sys/arch/powerpc/include/mutex.h b/sys/arch/powerpc/include/mutex.h index 7c5d36262e6..cffc66fab44 100644 --- a/sys/arch/powerpc/include/mutex.h +++ b/sys/arch/powerpc/include/mutex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mutex.h,v 1.2 2007/05/05 12:06:19 miod Exp $ */ +/* $OpenBSD: mutex.h,v 1.3 2014/01/22 11:01:15 kettenis Exp $ */ /* * Copyright (c) 2004 Artur Grabowski @@ -33,8 +33,26 @@ struct mutex { __volatile void *mtx_owner; }; -#define MUTEX_INITIALIZER(ipl) { (ipl), 0, NULL } +/* + * 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_TTY) ? IPL_TTY : (ipl)) +#else +#define __MUTEX_IPL(ipl) (ipl) +#endif +#define MUTEX_INITIALIZER(ipl) { __MUTEX_IPL((ipl)), 0, NULL } + +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__); \ @@ -44,6 +62,10 @@ struct mutex { 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_OLDIPL(mtx) (mtx)->mtx_oldcpl diff --git a/sys/arch/powerpc/powerpc/mutex.S b/sys/arch/powerpc/powerpc/mutex.S index 1e01d402fdc..4c5e1d626fe 100644 --- a/sys/arch/powerpc/powerpc/mutex.S +++ b/sys/arch/powerpc/powerpc/mutex.S @@ -1,4 +1,4 @@ -/* $OpenBSD: mutex.S,v 1.14 2011/08/29 20:21:44 drahn Exp $ */ +/* $OpenBSD: mutex.S,v 1.15 2014/01/22 11:01:15 kettenis Exp $ */ /* * Copyright (c) 2007 Dale Rahn @@ -24,7 +24,7 @@ /* XXX */ #define GET_CPUINFO(r) mfsprg r,0 -ENTRY(mtx_init) +ENTRY(__mtx_init) li %r5,0 stw %r4,MTX_WANTIPL(%r3) stw %r5,MTX_OLDCPL(%r3) -- cgit v1.2.3