NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/49862
The following reply was made to PR kern/49862; it has been noted by GNATS.
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
To: Thomas Klausner <wiz%NetBSD.org@localhost>
Cc: gnats-bugs%NetBSD.org@localhost
Subject: Re: kern/49862
Date: Wed, 20 May 2015 12:47:23 +0000
This is a multi-part message in MIME format.
--=_wia/yt5O+Lc5CSGr1omnrGEHa+dQ5NLv
Can you please try the attached patch, with `options LOCKDEBUG', to
enable lockdebug for the kind of mutex in question? (I haven't tested
the patch yet, so you may hit bugs in the patch first.)
--=_wia/yt5O+Lc5CSGr1omnrGEHa+dQ5NLv
Content-Type: text/plain; charset="ISO-8859-1"; name="ww_lockdebug"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="ww_lockdebug.patch"
Index: sys/external/bsd/drm2/include/linux/ww_mutex.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/external/bsd/drm2/include/linux/ww_mutex.h,v
retrieving revision 1.10
diff -p -u -r1.10 ww_mutex.h
--- sys/external/bsd/drm2/include/linux/ww_mutex.h 8 Jan 2015 23:35:47 -000=
0 1.10
+++ sys/external/bsd/drm2/include/linux/ww_mutex.h 20 May 2015 12:37:36 -00=
00
@@ -70,6 +70,9 @@ struct ww_mutex {
struct ww_class *wwm_class;
struct rb_tree wwm_waiters;
kcondvar_t wwm_cv;
+#ifdef LOCKDEBUG
+ bool wwm_debug;
+#endif
};
=20
/* XXX Make the nm output a little more greppable... */
Index: sys/external/bsd/drm2/linux/linux_ww_mutex.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/external/bsd/drm2/linux/linux_ww_mutex.c,v
retrieving revision 1.1
diff -p -u -r1.1 linux_ww_mutex.c
--- sys/external/bsd/drm2/linux/linux_ww_mutex.c 8 Jan 2015 23:35:47 -0000 =
1.1
+++ sys/external/bsd/drm2/linux/linux_ww_mutex.c 20 May 2015 12:37:36 -0000
@@ -35,12 +35,23 @@ __KERNEL_RCSID(0, "$NetBSD: linux_ww_mut
#include <sys/types.h>
#include <sys/atomic.h>
#include <sys/condvar.h>
+#include <sys/lockdebug.h>
#include <sys/lwp.h>
#include <sys/mutex.h>
#include <sys/rbtree.h>
=20
#include <linux/ww_mutex.h>
=20
+#define WW_WANTLOCK(WW) \
+ LOCKDEBUG_WANTLOCK((WW)->wwm_debug, (WW), \
+ (uintptr_t)__builtin_return_address(0), 0)
+#define WW_LOCKED(WW) \
+ LOCKDEBUG_LOCKED((WW)->wwm_debug, (WW), NULL, \
+ (uintptr_t)__builtin_return_address(0), 0)
+#define WW_UNLOCKED(WW) \
+ LOCKDEBUG_UNLOCKED((WW)->wwm_debug, (WW), \
+ (uintptr_t)__builtin_return_address(0), 0)
+
static int
ww_acquire_ctx_compare(void *cookie __unused, const void *va, const void *=
vb)
{
@@ -109,6 +120,51 @@ ww_acquire_fini(struct ww_acquire_ctx *c
ctx->wwx_owner =3D NULL;
}
=20
+static void
+ww_dump(volatile void *cookie)
+{
+ volatile struct ww_mutex *mutex =3D cookie;
+
+ printf_nolog("%-13s: ", "state");
+ switch (mutex->wwm_state) {
+ case WW_UNLOCKED:
+ printf_nolog("unlocked\n");
+ break;
+ case WW_OWNED:
+ printf_nolog("owned by lwp\n");
+ printf_nolog("%-13s: %p\n", "owner", mutex->wwm_u.owner);
+ printf_nolog("%-13s: %s\n", "waiters",
+ cv_has_waiters(__UNVOLATILE(&mutex->wwm_cv))
+ ? "yes" : "no");
+ break;
+ case WW_CTX:
+ printf_nolog("owned via ctx\n");
+ printf_nolog("%-13s: %p\n", "context", mutex->wwm_u.ctx);
+ printf_nolog("%-13s: %p\n", "lwp",
+ mutex->wwm_u.ctx->wwx_owner);
+ printf_nolog("%-13s: %s\n", "waiters",
+ cv_has_waiters(__UNVOLATILE(&mutex->wwm_cv))
+ ? "yes" : "no");
+ break;
+ case WW_WANTOWN:
+ printf_nolog("owned via ctx\n");
+ printf_nolog("%-13s: %p\n", "context", mutex->wwm_u.ctx);
+ printf_nolog("%-13s: %p\n", "lwp",
+ mutex->wwm_u.ctx->wwx_owner);
+ printf_nolog("%-13s: %s\n", "waiters", "yes (noctx)");
+ break;
+ default:
+ printf_nolog("unknown\n");
+ break;
+ }
+}
+
+static const lockops_t ww_lockops =3D {
+ .lo_name =3D "Wait/wound mutex",
+ .lo_type =3D LOCKOPS_SLEEP,
+ .lo_dump =3D ww_dump,
+};
+
void
ww_mutex_init(struct ww_mutex *mutex, struct ww_class *class)
{
@@ -122,17 +178,25 @@ ww_mutex_init(struct ww_mutex *mutex, st
mutex->wwm_class =3D class;
rb_tree_init(&mutex->wwm_waiters, &ww_acquire_ctx_rb_ops);
cv_init(&mutex->wwm_cv, "linuxwwm");
+#ifdef LOCKDEBUG
+ mutex->wwm_debug =3D LOCKDEBUG_ALLOC(mutex, &ww_lockops,
+ (uintptr_t)__builtin_return_address(0));
+#endif
}
=20
void
ww_mutex_destroy(struct ww_mutex *mutex)
{
=20
+ KASSERT(mutex->wwm_state =3D=3D WW_UNLOCKED);
+
+#ifdef LOCKDEBUG
+ LOCKDEBUG_FREE(mutex->wwm_debug, mutex);
+#endif
cv_destroy(&mutex->wwm_cv);
#if 0
rb_tree_destroy(&mutex->wwm_waiters, &ww_acquire_ctx_rb_ops);
#endif
- KASSERT(mutex->wwm_state =3D=3D WW_UNLOCKED);
mutex_destroy(&mutex->wwm_lock);
}
=20
@@ -267,6 +331,7 @@ retry: switch (mutex->wwm_state) {
case WW_UNLOCKED:
mutex->wwm_state =3D WW_OWNED;
mutex->wwm_u.owner =3D curlwp;
+ WW_LOCKED(mutex);
break;
case WW_OWNED:
KASSERTMSG((mutex->wwm_u.owner !=3D curlwp),
@@ -301,6 +366,7 @@ retry: switch (mutex->wwm_state) {
case WW_UNLOCKED:
mutex->wwm_state =3D WW_OWNED;
mutex->wwm_u.owner =3D curlwp;
+ WW_LOCKED(mutex);
break;
case WW_OWNED:
KASSERTMSG((mutex->wwm_u.owner !=3D curlwp),
@@ -335,6 +401,7 @@ int
ww_mutex_lock(struct ww_mutex *mutex, struct ww_acquire_ctx *ctx)
{
=20
+ WW_WANTLOCK(mutex);
ASSERT_SLEEPABLE();
=20
if (ctx =3D=3D NULL) {
@@ -357,6 +424,7 @@ retry: switch (mutex->wwm_state) {
case WW_UNLOCKED:
mutex->wwm_state =3D WW_CTX;
mutex->wwm_u.ctx =3D ctx;
+ WW_LOCKED(mutex);
goto locked;
case WW_OWNED:
KASSERTMSG((mutex->wwm_u.owner !=3D curlwp),
@@ -415,6 +483,7 @@ ww_mutex_lock_interruptible(struct ww_mu
{
int ret;
=20
+ WW_WANTLOCK(mutex);
ASSERT_SLEEPABLE();
=20
if (ctx =3D=3D NULL)
@@ -435,6 +504,7 @@ retry: switch (mutex->wwm_state) {
case WW_UNLOCKED:
mutex->wwm_state =3D WW_CTX;
mutex->wwm_u.ctx =3D ctx;
+ WW_LOCKED(mutex);
goto locked;
case WW_OWNED:
KASSERTMSG((mutex->wwm_u.owner !=3D curlwp),
@@ -499,6 +569,7 @@ void
ww_mutex_lock_slow(struct ww_mutex *mutex, struct ww_acquire_ctx *ctx)
{
=20
+ WW_WANTLOCK(mutex);
ASSERT_SLEEPABLE();
=20
if (ctx =3D=3D NULL) {
@@ -524,6 +595,7 @@ retry: switch (mutex->wwm_state) {
case WW_UNLOCKED:
mutex->wwm_state =3D WW_CTX;
mutex->wwm_u.ctx =3D ctx;
+ WW_LOCKED(mutex);
goto locked;
case WW_OWNED:
KASSERTMSG((mutex->wwm_u.owner !=3D curlwp),
@@ -561,6 +633,7 @@ ww_mutex_lock_slow_interruptible(struct=20
{
int ret;
=20
+ WW_WANTLOCK(mutex);
ASSERT_SLEEPABLE();
=20
if (ctx =3D=3D NULL)
@@ -584,6 +657,7 @@ retry: switch (mutex->wwm_state) {
case WW_UNLOCKED:
mutex->wwm_state =3D WW_CTX;
mutex->wwm_u.ctx =3D ctx;
+ WW_LOCKED(mutex);
goto locked;
case WW_OWNED:
KASSERTMSG((mutex->wwm_u.owner !=3D curlwp),
@@ -632,6 +706,7 @@ ww_mutex_trylock(struct ww_mutex *mutex)
if (mutex->wwm_state =3D=3D WW_UNLOCKED) {
mutex->wwm_state =3D WW_OWNED;
mutex->wwm_u.owner =3D curlwp;
+ WW_LOCKED(mutex);
ret =3D 1;
} else {
KASSERTMSG(((mutex->wwm_state !=3D WW_OWNED) ||
@@ -702,6 +777,7 @@ ww_mutex_unlock(struct ww_mutex *mutex)
mutex->wwm_state =3D WW_UNLOCKED;
break;
}
+ WW_UNLOCKED(mutex);
cv_broadcast(&mutex->wwm_cv);
mutex_exit(&mutex->wwm_lock);
}
--=_wia/yt5O+Lc5CSGr1omnrGEHa+dQ5NLv--
Home |
Main Index |
Thread Index |
Old Index