Clang's capability analysis can be made aware of functions that assert
that capabilities/locks are held.

Presence of these annotations causes the analysis to assume the
capability 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 <el...@google.com>
---
 include/linux/lockdep.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 67964dc4db95..5cea929b2219 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -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); 
__assert_cap(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)); __assert_cap(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)); 
__assert_shared_cap(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)                 __assert_cap(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)           __assert_cap(l)
+#define lockdep_assert_held_read(l)            __assert_shared_cap(l)
 #define lockdep_assert_held_once(l)            do { (void)(l); } while (0)
 #define lockdep_assert_none_held_once()        do { } while (0)
 
-- 
2.48.1.711.g2feabab25a-goog


Reply via email to