Here is a diff that makes mutexes raise their ipl to the highest level
that has interrupts that take the kernel lock. This is necessary for
the work dlg@ has been doing on making subsystems run without the
kernel lock.
This needs to be tested on an MP system, and unfortunately that's
something I cannot do.
Index: include/mutex.h
===================================================================
RCS file: /cvs/src/sys/arch/hppa/include/mutex.h,v
retrieving revision 1.4
diff -u -p -r1.4 mutex.h
--- include/mutex.h 10 Jan 2010 04:07:18 -0000 1.4
+++ include/mutex.h 29 Jan 2014 10:01:52 -0000
@@ -39,9 +39,24 @@ struct mutex {
void *mtx_owner;
};
-void mtx_init(struct mutex *, int);
+/*
+ * 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_AUDIO) ? IPL_AUDIO : (ipl))
+#else
+#define __MUTEX_IPL(ipl) (ipl)
+#endif
-#define MUTEX_INITIALIZER(ipl) { MUTEX_UNLOCKED, (ipl), 0, NULL }
+#define MUTEX_INITIALIZER(ipl) { MUTEX_UNLOCKED, __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 { \
Index: hppa/mutex.c
===================================================================
RCS file: /cvs/src/sys/arch/hppa/hppa/mutex.c,v
retrieving revision 1.11
diff -u -p -r1.11 mutex.c
--- hppa/mutex.c 20 Apr 2011 16:10:53 -0000 1.11
+++ hppa/mutex.c 29 Jan 2014 10:01:52 -0000
@@ -50,7 +50,7 @@ try_lock(struct mutex *mtx)
}
void
-mtx_init(struct mutex *mtx, int wantipl)
+__mtx_init(struct mutex *mtx, int wantipl)
{
mtx->mtx_lock[0] = 1;
mtx->mtx_lock[1] = 1;