Sorry for the late reply; I've been swamped and am behind on my upstream mail.
On Wed, Mar 20, 2013 at 12:55 PM, Rik van Riel <riel@xxxxxxxxxxx> wrote:+static inline int sem_lock(struct sem_array *sma, struct sembuf *sops,
+ int nsops)
+{
+ int locknum;
+ if (nsops == 1 && !sma->complex_count) {
+ struct sem *sem = sma->sem_base + sops->sem_num;
+
+ /* Lock just the semaphore we are interested in. */
+ spin_lock(&sem->lock);
+
+ /*
+ * If sma->complex_count was set while we were spinning,
+ * we may need to look at things we did not lock here.
+ */
+ if (unlikely(sma->complex_count)) {
+ spin_unlock(&sma->sem_perm.lock);
I believe this should be spin_unlock(&sem->lock) instead ?
+ goto lock_all;
+ }
+ locknum = sops->sem_num;
+ } else {
+ int i;
+ /* Lock the sem_array, and all the semaphore locks */
+ lock_all:
+ spin_lock(&sma->sem_perm.lock);
+ for (i = 0; i < sma->sem_nsems; i++) {
Do we have to lock every sem from the array instead of just the ones
that are being operated on in sops ?
(I'm not sure either way, as I don't fully understand the queueing of
complex ops)
If we want to keep the loop as is, then we may at least remove the
sops argument to sem_lock() since we only care about nsops.