diff options
| author | Marco Elver <elver@google.com> | 2025-12-19 16:40:06 +0100 |
|---|---|---|
| committer | Peter Zijlstra <peterz@infradead.org> | 2026-01-05 16:43:31 +0100 |
| commit | e4fd3be884cf33a42c5bcde087b0722a5b8f25ca (patch) | |
| tree | 1591c8f9bdd3d93af82d2a16f4e0be39227af859 /lib/test_context-analysis.c | |
| parent | 5e256db9325e75e9f000ddd64e4f1dbd2a6d8acd (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.c | 64 |
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)); |
