]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
lockdep: Annotate lockdep assertions for context analysis
authorMarco Elver <elver@google.com>
Fri, 19 Dec 2025 15:39:56 +0000 (16:39 +0100)
committerPeter Zijlstra <peterz@infradead.org>
Mon, 5 Jan 2026 15:43:28 +0000 (16:43 +0100)
Clang's context analysis can be made aware of functions that assert that
locks are held.

Presence of these annotations causes the analysis to assume the context
lock is held after calls to the annotated function, and avoid false
positives with complex control-flow; for example, where not all
control-flow paths in a function require a held lock, and therefore
marking the function with __must_hold(..) is inappropriate.

Signed-off-by: Marco Elver <elver@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20251219154418.3592607-8-elver@google.com
include/linux/lockdep.h

index dd634103b014ed8f98f25a1ad4416faf1734e95d..621566345406dde8237dfba5ae3184e858671e16 100644 (file)
@@ -282,16 +282,16 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
        do { WARN_ON_ONCE(debug_locks && !(cond)); } while (0)
 
 #define lockdep_assert_held(l)         \
-       lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
+       do { lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD); __assume_ctx_lock(l); } while (0)
 
 #define lockdep_assert_not_held(l)     \
        lockdep_assert(lockdep_is_held(l) != LOCK_STATE_HELD)
 
 #define lockdep_assert_held_write(l)   \
-       lockdep_assert(lockdep_is_held_type(l, 0))
+       do { lockdep_assert(lockdep_is_held_type(l, 0)); __assume_ctx_lock(l); } while (0)
 
 #define lockdep_assert_held_read(l)    \
-       lockdep_assert(lockdep_is_held_type(l, 1))
+       do { lockdep_assert(lockdep_is_held_type(l, 1)); __assume_shared_ctx_lock(l); } while (0)
 
 #define lockdep_assert_held_once(l)            \
        lockdep_assert_once(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
@@ -389,10 +389,10 @@ extern int lockdep_is_held(const void *);
 #define lockdep_assert(c)                      do { } while (0)
 #define lockdep_assert_once(c)                 do { } while (0)
 
-#define lockdep_assert_held(l)                 do { (void)(l); } while (0)
+#define lockdep_assert_held(l)                 __assume_ctx_lock(l)
 #define lockdep_assert_not_held(l)             do { (void)(l); } while (0)
-#define lockdep_assert_held_write(l)           do { (void)(l); } while (0)
-#define lockdep_assert_held_read(l)            do { (void)(l); } while (0)
+#define lockdep_assert_held_write(l)           __assume_ctx_lock(l)
+#define lockdep_assert_held_read(l)            __assume_shared_ctx_lock(l)
 #define lockdep_assert_held_once(l)            do { (void)(l); } while (0)
 #define lockdep_assert_none_held_once()        do { } while (0)