Skip to content

Commit b300534

Browse files
Davidlohr Buesohnaz
Davidlohr Bueso
authored andcommitted
ipc/sem: simplify wait-wake loop
Instead of using the reverse goto, we can simplify the flow and make it more language natural by just doing do-while instead. One would hope this is the standard way (or obviously just with a while bucle) that we do wait/wakeup handling in the kernel. The exact same logic is kept, just more indented. Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Davidlohr Bueso <[email protected]> Cc: Manfred Spraul <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 300c871 commit b300534

File tree

1 file changed

+51
-56
lines changed

1 file changed

+51
-56
lines changed

ipc/sem.c

+51-56
Original file line numberDiff line numberDiff line change
@@ -1980,71 +1980,66 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
19801980
sma->complex_count++;
19811981
}
19821982

1983-
sleep_again:
1984-
queue.status = -EINTR;
1985-
queue.sleeper = current;
1983+
do {
1984+
queue.status = -EINTR;
1985+
queue.sleeper = current;
19861986

1987-
__set_current_state(TASK_INTERRUPTIBLE);
1988-
sem_unlock(sma, locknum);
1989-
rcu_read_unlock();
1987+
__set_current_state(TASK_INTERRUPTIBLE);
1988+
sem_unlock(sma, locknum);
1989+
rcu_read_unlock();
19901990

1991-
if (timeout)
1992-
jiffies_left = schedule_timeout(jiffies_left);
1993-
else
1994-
schedule();
1991+
if (timeout)
1992+
jiffies_left = schedule_timeout(jiffies_left);
1993+
else
1994+
schedule();
19951995

1996-
/*
1997-
* fastpath: the semop has completed, either successfully or not, from
1998-
* the syscall pov, is quite irrelevant to us at this point; we're done.
1999-
*
2000-
* We _do_ care, nonetheless, about being awoken by a signal or
2001-
* spuriously. The queue.status is checked again in the slowpath (aka
2002-
* after taking sem_lock), such that we can detect scenarios where we
2003-
* were awakened externally, during the window between wake_q_add() and
2004-
* wake_up_q().
2005-
*/
2006-
error = READ_ONCE(queue.status);
2007-
if (error != -EINTR) {
20081996
/*
2009-
* User space could assume that semop() is a memory barrier:
2010-
* Without the mb(), the cpu could speculatively read in user
2011-
* space stale data that was overwritten by the previous owner
2012-
* of the semaphore.
1997+
* fastpath: the semop has completed, either successfully or not, from
1998+
* the syscall pov, is quite irrelevant to us at this point; we're done.
1999+
*
2000+
* We _do_ care, nonetheless, about being awoken by a signal or
2001+
* spuriously. The queue.status is checked again in the slowpath (aka
2002+
* after taking sem_lock), such that we can detect scenarios where we
2003+
* were awakened externally, during the window between wake_q_add() and
2004+
* wake_up_q().
20132005
*/
2014-
smp_mb();
2015-
goto out_free;
2016-
}
2017-
2018-
rcu_read_lock();
2019-
sma = sem_obtain_lock(ns, semid, sops, nsops, &locknum);
2020-
error = READ_ONCE(queue.status);
2006+
error = READ_ONCE(queue.status);
2007+
if (error != -EINTR) {
2008+
/*
2009+
* User space could assume that semop() is a memory barrier:
2010+
* Without the mb(), the cpu could speculatively read in user
2011+
* space stale data that was overwritten by the previous owner
2012+
* of the semaphore.
2013+
*/
2014+
smp_mb();
2015+
goto out_free;
2016+
}
20212017

2022-
/*
2023-
* Array removed? If yes, leave without sem_unlock().
2024-
*/
2025-
if (IS_ERR(sma)) {
2026-
rcu_read_unlock();
2027-
goto out_free;
2028-
}
2018+
rcu_read_lock();
2019+
sma = sem_obtain_lock(ns, semid, sops, nsops, &locknum);
2020+
error = READ_ONCE(queue.status);
20292021

2030-
/*
2031-
* If queue.status != -EINTR we are woken up by another process.
2032-
* Leave without unlink_queue(), but with sem_unlock().
2033-
*/
2034-
if (error != -EINTR)
2035-
goto out_unlock_free;
2022+
/*
2023+
* Array removed? If yes, leave without sem_unlock().
2024+
*/
2025+
if (IS_ERR(sma)) {
2026+
rcu_read_unlock();
2027+
goto out_free;
2028+
}
20362029

2037-
/*
2038-
* If an interrupt occurred we have to clean up the queue.
2039-
*/
2040-
if (timeout && jiffies_left == 0)
2041-
error = -EAGAIN;
2030+
/*
2031+
* If queue.status != -EINTR we are woken up by another process.
2032+
* Leave without unlink_queue(), but with sem_unlock().
2033+
*/
2034+
if (error != -EINTR)
2035+
goto out_unlock_free;
20422036

2043-
/*
2044-
* If the wakeup was spurious, just retry.
2045-
*/
2046-
if (error == -EINTR && !signal_pending(current))
2047-
goto sleep_again;
2037+
/*
2038+
* If an interrupt occurred we have to clean up the queue.
2039+
*/
2040+
if (timeout && jiffies_left == 0)
2041+
error = -EAGAIN;
2042+
} while (error == -EINTR && !signal_pending(current)); /* spurious */
20482043

20492044
unlink_queue(sma, &queue);
20502045

0 commit comments

Comments
 (0)