Skip to content

Commit 3e31f94

Browse files
shuahkhIngo Molnar
authored andcommitted
lockdep: Add lockdep_assert_not_held()
Some kernel functions must be called without holding a specific lock. Add lockdep_assert_not_held() to be used in these functions to detect incorrect calls while holding a lock. lockdep_assert_not_held() provides the opposite functionality of lockdep_assert_held() which is used to assert calls that require holding a specific lock. Incorporates suggestions from Peter Zijlstra to avoid misfires when lockdep_off() is employed. The need for lockdep_assert_not_held() came up in a discussion on ath10k patch. ath10k_drain_tx() and i915_vma_pin_ww() are examples of functions that can use lockdep_assert_not_held(). Signed-off-by: Shuah Khan <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Link: https://lore.kernel.org/linux-wireless/[email protected]/
1 parent 864b435 commit 3e31f94

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

include/linux/lockdep.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,12 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
301301

302302
#define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0)
303303

304-
#define lockdep_assert_held(l) do { \
305-
WARN_ON(debug_locks && !lockdep_is_held(l)); \
304+
#define lockdep_assert_held(l) do { \
305+
WARN_ON(debug_locks && lockdep_is_held(l) == 0); \
306+
} while (0)
307+
308+
#define lockdep_assert_not_held(l) do { \
309+
WARN_ON(debug_locks && lockdep_is_held(l) == 1); \
306310
} while (0)
307311

308312
#define lockdep_assert_held_write(l) do { \
@@ -393,7 +397,8 @@ extern int lockdep_is_held(const void *);
393397
#define lockdep_is_held_type(l, r) (1)
394398

395399
#define lockdep_assert_held(l) do { (void)(l); } while (0)
396-
#define lockdep_assert_held_write(l) do { (void)(l); } while (0)
400+
#define lockdep_assert_not_held(l) do { (void)(l); } while (0)
401+
#define lockdep_assert_held_write(l) do { (void)(l); } while (0)
397402
#define lockdep_assert_held_read(l) do { (void)(l); } while (0)
398403
#define lockdep_assert_held_once(l) do { (void)(l); } while (0)
399404

kernel/locking/lockdep.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5539,8 +5539,12 @@ noinstr int lock_is_held_type(const struct lockdep_map *lock, int read)
55395539
unsigned long flags;
55405540
int ret = 0;
55415541

5542+
/*
5543+
* Avoid false negative lockdep_assert_held() and
5544+
* lockdep_assert_not_held().
5545+
*/
55425546
if (unlikely(!lockdep_enabled()))
5543-
return 1; /* avoid false negative lockdep_assert_held() */
5547+
return -1;
55445548

55455549
raw_local_irq_save(flags);
55465550
check_flags(flags);

0 commit comments

Comments
 (0)