Add witness_is_owned(9)
which returns an indicator if the current thread owns the specified lock. Reviewed by: jah, markj Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D39477
This commit is contained in:
parent
afa8f8971b
commit
75fc6f86c3
@ -2429,6 +2429,32 @@ witness_restore(struct lock_object *lock, const char *file, int line)
|
|||||||
instance->li_line = line;
|
instance->li_line = line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
witness_find_instance(const struct lock_object *lock,
|
||||||
|
struct lock_instance **instance)
|
||||||
|
{
|
||||||
|
#ifdef INVARIANT_SUPPORT
|
||||||
|
struct lock_class *class;
|
||||||
|
|
||||||
|
if (lock->lo_witness == NULL || witness_watch < 1 || KERNEL_PANICKED())
|
||||||
|
return (false);
|
||||||
|
class = LOCK_CLASS(lock);
|
||||||
|
if ((class->lc_flags & LC_SLEEPLOCK) != 0) {
|
||||||
|
*instance = find_instance(curthread->td_sleeplocks, lock);
|
||||||
|
return (true);
|
||||||
|
} else if ((class->lc_flags & LC_SPINLOCK) != 0) {
|
||||||
|
*instance = find_instance(PCPU_GET(spinlocks), lock);
|
||||||
|
return (true);
|
||||||
|
} else {
|
||||||
|
kassert_panic("Lock (%s) %s is not sleep or spin!",
|
||||||
|
class->lc_name, lock->lo_name);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return (false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
witness_assert(const struct lock_object *lock, int flags, const char *file,
|
witness_assert(const struct lock_object *lock, int flags, const char *file,
|
||||||
int line)
|
int line)
|
||||||
@ -2437,18 +2463,9 @@ witness_assert(const struct lock_object *lock, int flags, const char *file,
|
|||||||
struct lock_instance *instance;
|
struct lock_instance *instance;
|
||||||
struct lock_class *class;
|
struct lock_class *class;
|
||||||
|
|
||||||
if (lock->lo_witness == NULL || witness_watch < 1 || KERNEL_PANICKED())
|
if (!witness_find_instance(lock, &instance))
|
||||||
return;
|
return;
|
||||||
class = LOCK_CLASS(lock);
|
class = LOCK_CLASS(lock);
|
||||||
if ((class->lc_flags & LC_SLEEPLOCK) != 0)
|
|
||||||
instance = find_instance(curthread->td_sleeplocks, lock);
|
|
||||||
else if ((class->lc_flags & LC_SPINLOCK) != 0)
|
|
||||||
instance = find_instance(PCPU_GET(spinlocks), lock);
|
|
||||||
else {
|
|
||||||
kassert_panic("Lock (%s) %s is not sleep or spin!",
|
|
||||||
class->lc_name, lock->lo_name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (flags) {
|
switch (flags) {
|
||||||
case LA_UNLOCKED:
|
case LA_UNLOCKED:
|
||||||
if (instance != NULL)
|
if (instance != NULL)
|
||||||
@ -2501,6 +2518,27 @@ witness_assert(const struct lock_object *lock, int flags, const char *file,
|
|||||||
#endif /* INVARIANT_SUPPORT */
|
#endif /* INVARIANT_SUPPORT */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks the ownership of the lock by curthread, consulting the witness list.
|
||||||
|
* Returns:
|
||||||
|
* 0 if witness is disabled or did not work
|
||||||
|
* -1 if not owned
|
||||||
|
* 1 if owned
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
witness_is_owned(const struct lock_object *lock)
|
||||||
|
{
|
||||||
|
#ifdef INVARIANT_SUPPORT
|
||||||
|
struct lock_instance *instance;
|
||||||
|
|
||||||
|
if (!witness_find_instance(lock, &instance))
|
||||||
|
return (0);
|
||||||
|
return (instance == NULL ? -1 : 1);
|
||||||
|
#else
|
||||||
|
return (0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
witness_setflag(struct lock_object *lock, int flag, int set)
|
witness_setflag(struct lock_object *lock, int flag, int set)
|
||||||
{
|
{
|
||||||
|
@ -237,6 +237,7 @@ int witness_list_locks(struct lock_list_entry **,
|
|||||||
int (*)(const char *, ...));
|
int (*)(const char *, ...));
|
||||||
int witness_warn(int, struct lock_object *, const char *, ...);
|
int witness_warn(int, struct lock_object *, const char *, ...);
|
||||||
void witness_assert(const struct lock_object *, int, const char *, int);
|
void witness_assert(const struct lock_object *, int, const char *, int);
|
||||||
|
int witness_is_owned(const struct lock_object *lock);
|
||||||
void witness_display_spinlock(struct lock_object *, struct thread *,
|
void witness_display_spinlock(struct lock_object *, struct thread *,
|
||||||
int (*)(const char *, ...));
|
int (*)(const char *, ...));
|
||||||
int witness_line(struct lock_object *);
|
int witness_line(struct lock_object *);
|
||||||
|
Loading…
Reference in New Issue
Block a user