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.
This commit is contained in:
parent
cc461cb6e3
commit
a3b9c0d553
@ -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)
|
||||
{
|
||||
|
@ -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 *);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user