summaryrefslogtreecommitdiffstats
path: root/include/linux/lockdep.h
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2016-11-29 22:32:25 -0500
committerDave Chinner <david@fromorbit.com>2016-11-29 22:32:25 -0500
commitf8319483f57f1ca22370f4150bb990aca7728a67 (patch)
tree348cff60f15f3282e5489fba4dfd46b6c958e533 /include/linux/lockdep.h
parent3816199506c7826983096fc65ed46f2733a47bb8 (diff)
locking/lockdep: Provide a type check for lock_is_held
Christoph requested lockdep_assert_held() variants that distinguish between held-for-read or held-for-write. Provide: int lock_is_held_type(struct lockdep_map *lock, int read) which takes the same argument as lock_acquire(.read) and matches it to the held_lock instance. Use of this function should be gated by the debug_locks variable. When that is 0 the return value of the lock_is_held_type() function is undefined. This is done to allow both negative and positive tests for holding locks. By default we provide (positive) lockdep_assert_held{,_exclusive,_read}() macros. Requested-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Tested-by: Jens Axboe <axboe@fb.com> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'include/linux/lockdep.h')
-rw-r--r--include/linux/lockdep.h25
1 files changed, 23 insertions, 2 deletions
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index c1458fede1f9..1e327bb80838 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -338,9 +338,18 @@ extern void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
338extern void lock_release(struct lockdep_map *lock, int nested, 338extern void lock_release(struct lockdep_map *lock, int nested,
339 unsigned long ip); 339 unsigned long ip);
340 340
341#define lockdep_is_held(lock) lock_is_held(&(lock)->dep_map) 341/*
342 * Same "read" as for lock_acquire(), except -1 means any.
343 */
344extern int lock_is_held_type(struct lockdep_map *lock, int read);
345
346static inline int lock_is_held(struct lockdep_map *lock)
347{
348 return lock_is_held_type(lock, -1);
349}
342 350
343extern int lock_is_held(struct lockdep_map *lock); 351#define lockdep_is_held(lock) lock_is_held(&(lock)->dep_map)
352#define lockdep_is_held_type(lock, r) lock_is_held_type(&(lock)->dep_map, (r))
344 353
345extern void lock_set_class(struct lockdep_map *lock, const char *name, 354extern void lock_set_class(struct lockdep_map *lock, const char *name,
346 struct lock_class_key *key, unsigned int subclass, 355 struct lock_class_key *key, unsigned int subclass,
@@ -372,6 +381,14 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
372 WARN_ON(debug_locks && !lockdep_is_held(l)); \ 381 WARN_ON(debug_locks && !lockdep_is_held(l)); \
373 } while (0) 382 } while (0)
374 383
384#define lockdep_assert_held_exclusive(l) do { \
385 WARN_ON(debug_locks && !lockdep_is_held_type(l, 0)); \
386 } while (0)
387
388#define lockdep_assert_held_read(l) do { \
389 WARN_ON(debug_locks && !lockdep_is_held_type(l, 1)); \
390 } while (0)
391
375#define lockdep_assert_held_once(l) do { \ 392#define lockdep_assert_held_once(l) do { \
376 WARN_ON_ONCE(debug_locks && !lockdep_is_held(l)); \ 393 WARN_ON_ONCE(debug_locks && !lockdep_is_held(l)); \
377 } while (0) 394 } while (0)
@@ -428,7 +445,11 @@ struct lock_class_key { };
428 445
429#define lockdep_depth(tsk) (0) 446#define lockdep_depth(tsk) (0)
430 447
448#define lockdep_is_held_type(l, r) (1)
449
431#define lockdep_assert_held(l) do { (void)(l); } while (0) 450#define lockdep_assert_held(l) do { (void)(l); } while (0)
451#define lockdep_assert_held_exclusive(l) do { (void)(l); } while (0)
452#define lockdep_assert_held_read(l) do { (void)(l); } while (0)
432#define lockdep_assert_held_once(l) do { (void)(l); } while (0) 453#define lockdep_assert_held_once(l) do { (void)(l); } while (0)
433 454
434#define lockdep_recursing(tsk) (0) 455#define lockdep_recursing(tsk) (0)