aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2003-07-31 18:50:58 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2003-07-31 18:50:58 +0000
commit1beccae67c75ac5f03c4df06fec2b700d7ee4587 (patch)
tree9af0a80a9c1231f3bf512b69e06a13cb6affaa6d
parent18a25b6126a66f1206bce3be75806c1f5e44bffa (diff)
Notes
-rw-r--r--sys/kern/subr_witness.c21
-rw-r--r--sys/sys/lock.h1
2 files changed, 22 insertions, 0 deletions
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 *);