@@ -1980,71 +1980,66 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
1980
1980
sma -> complex_count ++ ;
1981
1981
}
1982
1982
1983
- sleep_again :
1984
- queue .status = - EINTR ;
1985
- queue .sleeper = current ;
1983
+ do {
1984
+ queue .status = - EINTR ;
1985
+ queue .sleeper = current ;
1986
1986
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 ();
1990
1990
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 ();
1995
1995
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 ) {
2008
1996
/*
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().
2013
2005
*/
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
+ }
2021
2017
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 );
2029
2021
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
+ }
2036
2029
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 ;
2042
2036
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 */
2048
2043
2049
2044
unlink_queue (sma , & queue );
2050
2045
0 commit comments