Skip to content

Commit 31784cf

Browse files
ebiedermPeter Zijlstra
authored andcommitted
rwsem: Implement down_read_interruptible
In preparation for converting exec_update_mutex to a rwsem so that multiple readers can execute in parallel and not deadlock, add down_read_interruptible. This is needed for perf_event_open to be converted (with no semantic changes) from working on a mutex to wroking on a rwsem. Signed-off-by: Eric W. Biederman <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 0f9368b commit 31784cf

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

include/linux/rwsem.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ static inline int rwsem_is_contended(struct rw_semaphore *sem)
123123
* lock for reading
124124
*/
125125
extern void down_read(struct rw_semaphore *sem);
126+
extern int __must_check down_read_interruptible(struct rw_semaphore *sem);
126127
extern int __must_check down_read_killable(struct rw_semaphore *sem);
127128

128129
/*

kernel/locking/rwsem.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,6 +1345,18 @@ static inline void __down_read(struct rw_semaphore *sem)
13451345
}
13461346
}
13471347

1348+
static inline int __down_read_interruptible(struct rw_semaphore *sem)
1349+
{
1350+
if (!rwsem_read_trylock(sem)) {
1351+
if (IS_ERR(rwsem_down_read_slowpath(sem, TASK_INTERRUPTIBLE)))
1352+
return -EINTR;
1353+
DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem);
1354+
} else {
1355+
rwsem_set_reader_owned(sem);
1356+
}
1357+
return 0;
1358+
}
1359+
13481360
static inline int __down_read_killable(struct rw_semaphore *sem)
13491361
{
13501362
if (!rwsem_read_trylock(sem)) {
@@ -1495,6 +1507,20 @@ void __sched down_read(struct rw_semaphore *sem)
14951507
}
14961508
EXPORT_SYMBOL(down_read);
14971509

1510+
int __sched down_read_interruptible(struct rw_semaphore *sem)
1511+
{
1512+
might_sleep();
1513+
rwsem_acquire_read(&sem->dep_map, 0, 0, _RET_IP_);
1514+
1515+
if (LOCK_CONTENDED_RETURN(sem, __down_read_trylock, __down_read_interruptible)) {
1516+
rwsem_release(&sem->dep_map, _RET_IP_);
1517+
return -EINTR;
1518+
}
1519+
1520+
return 0;
1521+
}
1522+
EXPORT_SYMBOL(down_read_interruptible);
1523+
14981524
int __sched down_read_killable(struct rw_semaphore *sem)
14991525
{
15001526
might_sleep();

0 commit comments

Comments
 (0)