Re: [PATCH 08/14] lockdep: Introduce lockdep_assume_ctx_held()
From: Peter Zijlstra
Date: Thu Nov 05 2026 - 03:37:59 EST
On Mon, Nov 02, 2026 at 01:34:38PM -0800, Bart Van Assche wrote:
> Introduce lockdep_assume_ctx_held() and lockdep_assume_shared_ctx_held()
> for code that needs to inform Clang's context analysis that a lock is
> held in code paths where lock ownership cannot be proven at compile
> time, e.g. because the lock is accessed through a pointer alias that
> the analysis cannot resolve. These macros call respectively
> __assume_ctx_lock() and __assume_shared_ctx_lock() and also verify at
> runtime with lockdep that the lock is held. Store the macro argument in
> a local variable with a unique name such that it is evaluated only once
> and such that nested use of these macros does not cause shadowing. Rely
> on Clang's context analysis resolving that local variable to the
> expression it has been initialized with. Document both macros with
> kernel-doc comments, including that __assume_ctx_lock() and
> __assume_shared_ctx_lock() must be used for context locks without
> lockdep support, e.g. bit spinlocks and the RCU context tokens.
>
> Convert the lockdep_assert_held() tests in lib/test_context-analysis.c
> into lockdep_assume_ctx_held() tests and add tests for
> lockdep_assume_shared_ctx_held().
>
> This patch prepares for removing the context assumptions from
> lockdep_assert_held*().
So the only convincing rationale from 0/n for doing this was that the
current annotation can hide the need, and thus cause a lacking of
__must_hold() on the function.
I'm not sure I understand how this alternative form of the same avoids
that same problem, and the above doesn't seem to mention the whole
problem -- either that, or I just can't read this morning.
> +#define _lockdep_assume_shared_ctx_held(var, uniq) \
> + do { \
> + __auto_type uniq = (var); \
> + \
> + __assume_shared_ctx_lock(uniq); \
> + lockdep_assert_held(uniq); \
> + } while (0)
> +
> +/**
> + * lockdep_assume_shared_ctx_held() - assume and verify shared lock ownership
> + * @var: context lock instance pointer
> + *
> + * Instruct the compiler's context analysis to assume that @var is held with
> + * shared access from this point on and verify at runtime with
> + * lockdep_assert_held() that @var is held. Use this macro for reader-writer
> + * locks, e.g. rwlock_t and struct rw_semaphore, in code paths where shared
> + * lock ownership cannot be proven at compile time. @var is evaluated only
> + * once.
> + *
> + * Since lockdep_assert_held() is used, no lockdep warning is reported if
> + * @var is held for writing instead of for reading. Holding a lock
> + * exclusively implies that shared access is allowed. Use
> + * lockdep_assume_ctx_held() if exclusive access is required.
We do have lockdep_assert_held_read(), which then requires a shared
access.
> + * @var must point at a lock object that is tracked by lockdep, i.e. that
> + * has a dep_map member. For context locks that are not tracked by lockdep,
> + * e.g. the RCU context tokens, use __assume_shared_ctx_lock() instead.
> + */
> +#define lockdep_assume_shared_ctx_held(var) \
> + _lockdep_assume_shared_ctx_held(var, __UNIQUE_ID(ctx_lock))
> +
> #ifdef CONFIG_PROVE_LOCKING
> void lockdep_set_lock_cmp_fn(struct lockdep_map *, lock_cmp_fn, lock_print_fn);