From 1beccae67c75ac5f03c4df06fec2b700d7ee4587 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 31 Jul 2003 18:50:58 +0000 Subject: Add a new function to look for a spinlock's instance when it is held by another thread. We use the td_oncpu member of the other field to locate it's associated CPU and then search the that CPU's list of spin locks contained in its per-CPU data. This is not always safe and may in fact panic or just not work, but it is useful in at least one case. --- sys/kern/subr_witness.c | 21 +++++++++++++++++++++ sys/sys/lock.h | 1 + 2 files changed, 22 insertions(+) diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c index c0d111f7aa46..10891be2fcf5 100644 --- a/sys/kern/subr_witness.c +++ b/sys/kern/subr_witness.c @@ -1593,6 +1593,27 @@ witness_list_locks(struct lock_list_entry **lock_list) return (nheld); } +/* + * This is a bit risky at best. We call this function when we have timed + * out acquiring a spin lock, and we assume that the other CPU is stuck + * with this lock held. So, we go groveling around in the other CPU's + * per-cpu data to try to find the lock instance for this spin lock to + * see when it was last acquired. + */ +void +witness_display_spinlock(struct lock_object *lock, struct thread *owner) +{ + struct lock_instance *instance; + struct pcpu *pc; + + if (owner->td_critnest == 0 || owner->td_oncpu == NOCPU) + return; + pc = pcpu_find(owner->td_oncpu); + instance = find_instance(pc->pc_spinlocks, lock); + if (instance != NULL) + witness_list_lock(instance); +} + void witness_save(struct lock_object *lock, const char **filep, int *linep) { diff --git a/sys/sys/lock.h b/sys/sys/lock.h index 106018bfb333..dcf7b772217a 100644 --- a/sys/sys/lock.h +++ b/sys/sys/lock.h @@ -206,6 +206,7 @@ void witness_restore(struct lock_object *, const char *, int); int witness_list_locks(struct lock_list_entry **); int witness_warn(int, struct lock_object *, const char *, ...); void witness_assert(struct lock_object *, int, const char *, int); +void witness_display_spinlock(struct lock_object *, struct thread *); int witness_line(struct lock_object *); const char *witness_file(struct lock_object *); -- cgit v1.3