Commit 1b963c81b14509e330e0fe3218b645ece2738dc5
Committed by
Linus Torvalds
1 parent
fef6c12e88
Exists in
master
and in
20 other branches
lockdep, rwsem: provide down_write_nest_lock()
down_write_nest_lock() provides a means to annotate locking scenario where an outer lock is guaranteed to serialize the order nested locks are being acquired. This is analogoue to already existing mutex_lock_nest_lock() and spin_lock_nest_lock(). Signed-off-by: Jiri Kosina <jkosina@suse.cz> Cc: Rik van Riel <riel@redhat.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Mel Gorman <mel@csn.ul.ie> Tested-by: Sedat Dilek <sedat.dilek@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 3 changed files with 22 additions and 0 deletions Side-by-side Diff
include/linux/lockdep.h
... | ... | @@ -524,14 +524,17 @@ |
524 | 524 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
525 | 525 | # ifdef CONFIG_PROVE_LOCKING |
526 | 526 | # define rwsem_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 2, NULL, i) |
527 | +# define rwsem_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 2, n, i) | |
527 | 528 | # define rwsem_acquire_read(l, s, t, i) lock_acquire(l, s, t, 1, 2, NULL, i) |
528 | 529 | # else |
529 | 530 | # define rwsem_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 1, NULL, i) |
531 | +# define rwsem_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 1, n, i) | |
530 | 532 | # define rwsem_acquire_read(l, s, t, i) lock_acquire(l, s, t, 1, 1, NULL, i) |
531 | 533 | # endif |
532 | 534 | # define rwsem_release(l, n, i) lock_release(l, n, i) |
533 | 535 | #else |
534 | 536 | # define rwsem_acquire(l, s, t, i) do { } while (0) |
537 | +# define rwsem_acquire_nest(l, s, t, n, i) do { } while (0) | |
535 | 538 | # define rwsem_acquire_read(l, s, t, i) do { } while (0) |
536 | 539 | # define rwsem_release(l, n, i) do { } while (0) |
537 | 540 | #endif |
include/linux/rwsem.h
... | ... | @@ -125,8 +125,17 @@ |
125 | 125 | */ |
126 | 126 | extern void down_read_nested(struct rw_semaphore *sem, int subclass); |
127 | 127 | extern void down_write_nested(struct rw_semaphore *sem, int subclass); |
128 | +extern void _down_write_nest_lock(struct rw_semaphore *sem, struct lockdep_map *nest_lock); | |
129 | + | |
130 | +# define down_write_nest_lock(sem, nest_lock) \ | |
131 | +do { \ | |
132 | + typecheck(struct lockdep_map *, &(nest_lock)->dep_map); \ | |
133 | + _down_write_nest_lock(sem, &(nest_lock)->dep_map); \ | |
134 | +} while (0); | |
135 | + | |
128 | 136 | #else |
129 | 137 | # define down_read_nested(sem, subclass) down_read(sem) |
138 | +# define down_write_nest_lock(sem, nest_lock) down_read(sem) | |
130 | 139 | # define down_write_nested(sem, subclass) down_write(sem) |
131 | 140 | #endif |
132 | 141 |
kernel/rwsem.c
... | ... | @@ -116,6 +116,16 @@ |
116 | 116 | |
117 | 117 | EXPORT_SYMBOL(down_read_nested); |
118 | 118 | |
119 | +void _down_write_nest_lock(struct rw_semaphore *sem, struct lockdep_map *nest) | |
120 | +{ | |
121 | + might_sleep(); | |
122 | + rwsem_acquire_nest(&sem->dep_map, 0, 0, nest, _RET_IP_); | |
123 | + | |
124 | + LOCK_CONTENDED(sem, __down_write_trylock, __down_write); | |
125 | +} | |
126 | + | |
127 | +EXPORT_SYMBOL(_down_write_nest_lock); | |
128 | + | |
119 | 129 | void down_write_nested(struct rw_semaphore *sem, int subclass) |
120 | 130 | { |
121 | 131 | might_sleep(); |