summaryrefslogtreecommitdiff
path: root/lib/test_context-analysis.c
diff options
context:
space:
mode:
authorMarco Elver <elver@google.com>2025-12-19 16:40:06 +0100
committerPeter Zijlstra <peterz@infradead.org>2026-01-05 16:43:31 +0100
commite4fd3be884cf33a42c5bcde087b0722a5b8f25ca (patch)
tree1591c8f9bdd3d93af82d2a16f4e0be39227af859 /lib/test_context-analysis.c
parent5e256db9325e75e9f000ddd64e4f1dbd2a6d8acd (diff)
locking/rwsem: Support Clang's context analysis
Add support for Clang's context analysis for rw_semaphore. Signed-off-by: Marco Elver <elver@google.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://patch.msgid.link/20251219154418.3592607-18-elver@google.com
Diffstat (limited to 'lib/test_context-analysis.c')
-rw-r--r--lib/test_context-analysis.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/lib/test_context-analysis.c b/lib/test_context-analysis.c
index 39e03790c0f6..1c96c56cf873 100644
--- a/lib/test_context-analysis.c
+++ b/lib/test_context-analysis.c
@@ -8,6 +8,7 @@
#include <linux/build_bug.h>
#include <linux/mutex.h>
#include <linux/rcupdate.h>
+#include <linux/rwsem.h>
#include <linux/seqlock.h>
#include <linux/spinlock.h>
#include <linux/srcu.h>
@@ -262,6 +263,69 @@ static void __used test_seqlock_scoped(struct test_seqlock_data *d)
}
}
+struct test_rwsem_data {
+ struct rw_semaphore sem;
+ int counter __guarded_by(&sem);
+};
+
+static void __used test_rwsem_init(struct test_rwsem_data *d)
+{
+ init_rwsem(&d->sem);
+ d->counter = 0;
+}
+
+static void __used test_rwsem_reader(struct test_rwsem_data *d)
+{
+ down_read(&d->sem);
+ (void)d->counter;
+ up_read(&d->sem);
+
+ if (down_read_trylock(&d->sem)) {
+ (void)d->counter;
+ up_read(&d->sem);
+ }
+}
+
+static void __used test_rwsem_writer(struct test_rwsem_data *d)
+{
+ down_write(&d->sem);
+ d->counter++;
+ up_write(&d->sem);
+
+ down_write(&d->sem);
+ d->counter++;
+ downgrade_write(&d->sem);
+ (void)d->counter;
+ up_read(&d->sem);
+
+ if (down_write_trylock(&d->sem)) {
+ d->counter++;
+ up_write(&d->sem);
+ }
+}
+
+static void __used test_rwsem_assert(struct test_rwsem_data *d)
+{
+ rwsem_assert_held_nolockdep(&d->sem);
+ d->counter++;
+}
+
+static void __used test_rwsem_guard(struct test_rwsem_data *d)
+{
+ { guard(rwsem_read)(&d->sem); (void)d->counter; }
+ { guard(rwsem_write)(&d->sem); d->counter++; }
+}
+
+static void __used test_rwsem_cond_guard(struct test_rwsem_data *d)
+{
+ scoped_cond_guard(rwsem_read_try, return, &d->sem) {
+ (void)d->counter;
+ }
+ scoped_cond_guard(rwsem_write_try, return, &d->sem) {
+ d->counter++;
+ }
+}
+
struct test_bit_spinlock_data {
unsigned long bits;
int counter __guarded_by(__bitlock(3, &bits));