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>
This commit is contained in:
parent
fef6c12e88
commit
1b963c81b1
|
@ -524,14 +524,17 @@ static inline void print_irqtrace_events(struct task_struct *curr)
|
||||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||||
# ifdef CONFIG_PROVE_LOCKING
|
# ifdef CONFIG_PROVE_LOCKING
|
||||||
# define rwsem_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 2, NULL, i)
|
# define rwsem_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 2, NULL, i)
|
||||||
|
# define rwsem_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 2, n, i)
|
||||||
# define rwsem_acquire_read(l, s, t, i) lock_acquire(l, s, t, 1, 2, NULL, i)
|
# define rwsem_acquire_read(l, s, t, i) lock_acquire(l, s, t, 1, 2, NULL, i)
|
||||||
# else
|
# else
|
||||||
# define rwsem_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 1, NULL, i)
|
# define rwsem_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 1, NULL, i)
|
||||||
|
# define rwsem_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 1, n, i)
|
||||||
# define rwsem_acquire_read(l, s, t, i) lock_acquire(l, s, t, 1, 1, NULL, i)
|
# define rwsem_acquire_read(l, s, t, i) lock_acquire(l, s, t, 1, 1, NULL, i)
|
||||||
# endif
|
# endif
|
||||||
# define rwsem_release(l, n, i) lock_release(l, n, i)
|
# define rwsem_release(l, n, i) lock_release(l, n, i)
|
||||||
#else
|
#else
|
||||||
# define rwsem_acquire(l, s, t, i) do { } while (0)
|
# define rwsem_acquire(l, s, t, i) do { } while (0)
|
||||||
|
# define rwsem_acquire_nest(l, s, t, n, i) do { } while (0)
|
||||||
# define rwsem_acquire_read(l, s, t, i) do { } while (0)
|
# define rwsem_acquire_read(l, s, t, i) do { } while (0)
|
||||||
# define rwsem_release(l, n, i) do { } while (0)
|
# define rwsem_release(l, n, i) do { } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -125,8 +125,17 @@ extern void downgrade_write(struct rw_semaphore *sem);
|
||||||
*/
|
*/
|
||||||
extern void down_read_nested(struct rw_semaphore *sem, int subclass);
|
extern void down_read_nested(struct rw_semaphore *sem, int subclass);
|
||||||
extern void down_write_nested(struct rw_semaphore *sem, int subclass);
|
extern void down_write_nested(struct rw_semaphore *sem, int subclass);
|
||||||
|
extern void _down_write_nest_lock(struct rw_semaphore *sem, struct lockdep_map *nest_lock);
|
||||||
|
|
||||||
|
# define down_write_nest_lock(sem, nest_lock) \
|
||||||
|
do { \
|
||||||
|
typecheck(struct lockdep_map *, &(nest_lock)->dep_map); \
|
||||||
|
_down_write_nest_lock(sem, &(nest_lock)->dep_map); \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
# define down_read_nested(sem, subclass) down_read(sem)
|
# define down_read_nested(sem, subclass) down_read(sem)
|
||||||
|
# define down_write_nest_lock(sem, nest_lock) down_read(sem)
|
||||||
# define down_write_nested(sem, subclass) down_write(sem)
|
# define down_write_nested(sem, subclass) down_write(sem)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,16 @@ void down_read_nested(struct rw_semaphore *sem, int subclass)
|
||||||
|
|
||||||
EXPORT_SYMBOL(down_read_nested);
|
EXPORT_SYMBOL(down_read_nested);
|
||||||
|
|
||||||
|
void _down_write_nest_lock(struct rw_semaphore *sem, struct lockdep_map *nest)
|
||||||
|
{
|
||||||
|
might_sleep();
|
||||||
|
rwsem_acquire_nest(&sem->dep_map, 0, 0, nest, _RET_IP_);
|
||||||
|
|
||||||
|
LOCK_CONTENDED(sem, __down_write_trylock, __down_write);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(_down_write_nest_lock);
|
||||||
|
|
||||||
void down_write_nested(struct rw_semaphore *sem, int subclass)
|
void down_write_nested(struct rw_semaphore *sem, int subclass)
|
||||||
{
|
{
|
||||||
might_sleep();
|
might_sleep();
|
||||||
|
|
Loading…
Reference in New Issue