Page MenuHomeFreeBSD

D39477.diff
No OneTemporary

D39477.diff

diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c
--- a/sys/kern/subr_witness.c
+++ b/sys/kern/subr_witness.c
@@ -2429,6 +2429,32 @@
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
witness_assert(const struct lock_object *lock, int flags, const char *file,
int line)
@@ -2437,18 +2463,9 @@
struct lock_instance *instance;
struct lock_class *class;
- if (lock->lo_witness == NULL || witness_watch < 1 || KERNEL_PANICKED())
+ if (!witness_find_instance(lock, &instance))
return;
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) {
case LA_UNLOCKED:
if (instance != NULL)
@@ -2501,6 +2518,27 @@
#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
witness_setflag(struct lock_object *lock, int flag, int set)
{
diff --git a/sys/sys/lock.h b/sys/sys/lock.h
--- a/sys/sys/lock.h
+++ b/sys/sys/lock.h
@@ -237,6 +237,7 @@
int (*)(const char *, ...));
int witness_warn(int, struct lock_object *, const char *, ...);
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 *,
int (*)(const char *, ...));
int witness_line(struct lock_object *);

File Metadata

Mime Type
text/plain
Expires
Mon, Feb 23, 9:03 AM (5 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28954134
Default Alt Text
D39477.diff (2 KB)

Event Timeline