Skip to content

Commit 5149cba

Browse files
Waiman-LongIngo Molnar
authored andcommitted
locking/rwsem: Add DEBUG_RWSEMS to look for lock/unlock mismatches
For a rwsem, locking can either be exclusive or shared. The corresponding exclusive or shared unlock must be used. Otherwise, the protected data structures may get corrupted or the lock may be in an inconsistent state. In order to detect such anomaly, a new configuration option DEBUG_RWSEMS is added which can be enabled to look for such mismatches and print warnings that that happens. Signed-off-by: Waiman Long <[email protected]> Acked-by: Davidlohr Bueso <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Paul E. McKenney <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 169310f commit 5149cba

File tree

3 files changed

+19
-1
lines changed

3 files changed

+19
-1
lines changed

kernel/locking/rwsem.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ EXPORT_SYMBOL(down_write_trylock);
117117
void up_read(struct rw_semaphore *sem)
118118
{
119119
rwsem_release(&sem->dep_map, 1, _RET_IP_);
120+
DEBUG_RWSEMS_WARN_ON(sem->owner != RWSEM_READER_OWNED);
120121

121122
__up_read(sem);
122123
}
@@ -129,6 +130,7 @@ EXPORT_SYMBOL(up_read);
129130
void up_write(struct rw_semaphore *sem)
130131
{
131132
rwsem_release(&sem->dep_map, 1, _RET_IP_);
133+
DEBUG_RWSEMS_WARN_ON(sem->owner != current);
132134

133135
rwsem_clear_owner(sem);
134136
__up_write(sem);
@@ -142,6 +144,7 @@ EXPORT_SYMBOL(up_write);
142144
void downgrade_write(struct rw_semaphore *sem)
143145
{
144146
lock_downgrade(&sem->dep_map, _RET_IP_);
147+
DEBUG_RWSEMS_WARN_ON(sem->owner != current);
145148

146149
rwsem_set_reader_owned(sem);
147150
__downgrade_write(sem);
@@ -211,6 +214,7 @@ EXPORT_SYMBOL(down_write_killable_nested);
211214

212215
void up_read_non_owner(struct rw_semaphore *sem)
213216
{
217+
DEBUG_RWSEMS_WARN_ON(sem->owner != RWSEM_READER_OWNED);
214218
__up_read(sem);
215219
}
216220

kernel/locking/rwsem.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616
*/
1717
#define RWSEM_READER_OWNED ((struct task_struct *)1UL)
1818

19+
#ifdef CONFIG_DEBUG_RWSEMS
20+
# define DEBUG_RWSEMS_WARN_ON(c) DEBUG_LOCKS_WARN_ON(c)
21+
#else
22+
# define DEBUG_RWSEMS_WARN_ON(c)
23+
#endif
24+
1925
#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
2026
/*
2127
* All writes to owner are protected by WRITE_ONCE() to make sure that
@@ -41,7 +47,7 @@ static inline void rwsem_set_reader_owned(struct rw_semaphore *sem)
4147
* do a write to the rwsem cacheline when it is really necessary
4248
* to minimize cacheline contention.
4349
*/
44-
if (sem->owner != RWSEM_READER_OWNED)
50+
if (READ_ONCE(sem->owner) != RWSEM_READER_OWNED)
4551
WRITE_ONCE(sem->owner, RWSEM_READER_OWNED);
4652
}
4753

lib/Kconfig.debug

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,6 +1075,13 @@ config DEBUG_WW_MUTEX_SLOWPATH
10751075
even a debug kernel. If you are a driver writer, enable it. If
10761076
you are a distro, do not.
10771077

1078+
config DEBUG_RWSEMS
1079+
bool "RW Semaphore debugging: basic checks"
1080+
depends on DEBUG_KERNEL && RWSEM_SPIN_ON_OWNER
1081+
help
1082+
This debugging feature allows mismatched rw semaphore locks and unlocks
1083+
to be detected and reported.
1084+
10781085
config DEBUG_LOCK_ALLOC
10791086
bool "Lock debugging: detect incorrect freeing of live locks"
10801087
depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
@@ -1097,6 +1104,7 @@ config PROVE_LOCKING
10971104
select DEBUG_SPINLOCK
10981105
select DEBUG_MUTEXES
10991106
select DEBUG_RT_MUTEXES if RT_MUTEXES
1107+
select DEBUG_RWSEMS if RWSEM_SPIN_ON_OWNER
11001108
select DEBUG_LOCK_ALLOC
11011109
select TRACE_IRQFLAGS
11021110
default n

0 commit comments

Comments
 (0)