Hmean sembench-sem-482 965735.00 ( 0.00%) 1040313.00 ( 7.72%)
Signed-off-by: Davidlohr Bueso <dbueso@xxxxxxx>Nice speedup, nice amount of removed duplicated code.
---
ipc/sem.c | 268 +++++++++++++++++++-------------------------------------------
1 file changed, 83 insertions(+), 185 deletions(-)
diff --git a/ipc/sem.c b/ipc/sem.c[...]
index a4e8bb2fae38..86467b5b78ad 100644
- error = get_queue_result(&queue);What is the purpose of the !signal_pending()?
-
- if (error != -EINTR) {
- /* fast path: update_queue already obtained all requested
- * resources.
- * Perform a smp_mb(): User space could assume that semop()
- * is a memory barrier: Without the mb(), the cpu could
- * speculatively read in user space stale data that was
- * overwritten by the previous owner of the semaphore.
+ /*
+ * fastpath: the semop has completed, either successfully or not, from
+ * the syscall pov, is quite irrelevant to us at this point; we're done.
+ *
+ * We _do_ care, nonetheless, about being awoken by a signal or spuriously.
+ * The queue.status is checked again in the slowpath (aka after taking
+ * sem_lock), such that we can detect scenarios where we were awakened
+ * externally, during the window between wake_q_add() and wake_up_q().
+ */
+ if ((error = queue.status) != -EINTR && !signal_pending(current)) {
+ /*
+ * User space could assume that semop() is a memory barrier:
+ * Without the mb(), the cpu could speculatively read in user
+ * space stale data that was overwritten by the previous owner
+ * of the semaphore.
*/
smp_mb();
-
goto out_free;
}
rcu_read_lock();
sma = sem_obtain_lock(ns, semid, sops, nsops, &locknum);