summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2001-04-09 22:34:05 +0000
committerjhb <jhb@FreeBSD.org>2001-04-09 22:34:05 +0000
commit242556cfec5c1d6e21f25d2f6d8d81f3c6a1116d (patch)
treeb017e9b23dbb22d040530abe24e9c85fe29f8bea
parentfec08fc485d6c0c3fe82475062f2e4d10192b32a (diff)
downloadFreeBSD-src-242556cfec5c1d6e21f25d2f6d8d81f3c6a1116d.zip
FreeBSD-src-242556cfec5c1d6e21f25d2f6d8d81f3c6a1116d.tar.gz
Maintain a reference count on the witness struct. When the reference
count drops to 0 in witness_destroy, set the w_name and w_file pointers to point to the string "(dead)" and the w_line field to 0. This way, if a mutex of a given name is used only in a module, then as long as all mutexes in the module are destroyed when the module is unloaded, witness will not maintain stale references to the mutex's name in the module's data section causing a panic later on when the w_name or w_file field's are examined.
-rw-r--r--sys/kern/subr_witness.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c
index 87119a4..aaefb2e 100644
--- a/sys/kern/subr_witness.c
+++ b/sys/kern/subr_witness.c
@@ -360,6 +360,7 @@ witness_init(struct lock_object *lock)
void
witness_destroy(struct lock_object *lock)
{
+ struct witness *w;
if (witness_cold)
panic("lock (%s) %s destroyed while witness_cold",
@@ -373,6 +374,18 @@ witness_destroy(struct lock_object *lock)
panic("lock (%s) %s destroyed while held",
lock->lo_class->lc_name, lock->lo_name);
+ w = lock->lo_witness;
+ if (w != NULL) {
+ mtx_lock_spin(&w_mtx);
+ w->w_refcount--;
+ if (w->w_refcount == 0) {
+ w->w_name = "(dead)";
+ w->w_file = "(dead)";
+ w->w_line = 0;
+ }
+ mtx_unlock_spin(&w_mtx);
+ }
+
mtx_lock(&all_mtx);
lock_cur_cnt--;
STAILQ_REMOVE(&all_locks, lock, lock_object, lo_list);
@@ -751,6 +764,7 @@ enroll(const char *description, struct lock_class *lock_class)
mtx_lock_spin(&w_mtx);
STAILQ_FOREACH(w, &w_all, w_list) {
if (strcmp(description, w->w_name) == 0) {
+ w->w_refcount++;
mtx_unlock_spin(&w_mtx);
if (lock_class != w->w_class)
panic(
@@ -770,6 +784,7 @@ enroll(const char *description, struct lock_class *lock_class)
return (NULL);
w->w_name = description;
w->w_class = lock_class;
+ w->w_refcount = 1;
STAILQ_INSERT_HEAD(&w_all, w, w_list);
if (lock_class->lc_flags & LC_SPINLOCK)
STAILQ_INSERT_HEAD(&w_spin, w, w_typelist);
OpenPOWER on IntegriCloud