diff options
author | attilio <attilio@FreeBSD.org> | 2008-10-20 19:22:16 +0000 |
---|---|---|
committer | attilio <attilio@FreeBSD.org> | 2008-10-20 19:22:16 +0000 |
commit | 42c5b05453c3cc80df893796dd9462c5f8696c32 (patch) | |
tree | 472fb424ffa15e70a97f972d358d872b23a846e2 /sys | |
parent | 4e82aa0737796e3d57621842ae7914381cf006c1 (diff) | |
download | FreeBSD-src-42c5b05453c3cc80df893796dd9462c5f8696c32.zip FreeBSD-src-42c5b05453c3cc80df893796dd9462c5f8696c32.tar.gz |
In the actual code for witness_warn:
- If there aren't spinlocks held, but there are problems with old
sleeplocks, they are not reported.
- If the spinlock found is not the only one, problems are not reported.
Fix these 2 problems.
Reported by: tegge
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/subr_witness.c | 31 |
1 files changed, 12 insertions, 19 deletions
diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c index ee36ae0..48c4b5c 100644 --- a/sys/kern/subr_witness.c +++ b/sys/kern/subr_witness.c @@ -1628,13 +1628,7 @@ witness_warn(int flags, struct lock_object *lock, const char *fmt, ...) */ sched_pin(); lock_list = PCPU_GET(spinlocks); - if (lock_list != NULL) { - - /* Empty list? */ - if (lock_list->ll_count == 0) { - sched_unpin(); - return (n); - } + if (lock_list != NULL && lock_list->ll_count != 0) { sched_unpin(); /* @@ -1644,18 +1638,17 @@ witness_warn(int flags, struct lock_object *lock, const char *fmt, ...) * should hold. */ lock1 = &lock_list->ll_children[lock_list->ll_count - 1]; - if (lock1->li_lock == lock) - return (n); - - if (n == 0) { - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); - printf(" with the following"); - if (flags & WARN_SLEEPOK) - printf(" non-sleepable"); - printf(" locks held:\n"); - } + if (lock_list->ll_count == 1 && lock_list->ll_next == NULL && + lock1->li_lock == lock && n == 0) + return (0); + + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + printf(" with the following"); + if (flags & WARN_SLEEPOK) + printf(" non-sleepable"); + printf(" locks held:\n"); n += witness_list_locks(&lock_list); } else sched_unpin(); |