diff options
author | jhb <jhb@FreeBSD.org> | 2001-04-09 22:34:05 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2001-04-09 22:34:05 +0000 |
commit | 242556cfec5c1d6e21f25d2f6d8d81f3c6a1116d (patch) | |
tree | b017e9b23dbb22d040530abe24e9c85fe29f8bea /sys/kern | |
parent | fec08fc485d6c0c3fe82475062f2e4d10192b32a (diff) | |
download | FreeBSD-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.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/subr_witness.c | 15 |
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); |