Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F145626963
D39477.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D39477.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D39477: ASSERT_VOP_LOCKED(): restore diagnostic for the witness use case
Attached
Detach File
Event Timeline
Log In to Comment