Hi Linus,
I think I found another bug in the kernel. If "wait for zero"
operation on an IPC semaphore is going to be blocked,
it then clobbers (resets to 0) PID of the process, which last
modified the semaphore (obtainable via semctl(...GETPID...)).
This bug is simply because of undo in 'try_atomic_semop' always
restores PID of the last process that modified the semaphore, while
"wait for zero" does not save that PID:
file ipc/sem.c, try_atomic_semop():
---------------------------------------------------------------------------
if (!sem_op && curr->semval) /*!!!!!!*/
goto would_block;
curr->sempid = (curr->sempid << 16) | pid; /*!!!!!!*/
........
would_block:
if (sop->sem_flg & IPC_NOWAIT)
result = -EAGAIN;
else
result = 1;
undo:
while (sop >= sops) {
curr = sma->sem_base + sop->sem_num;
curr->semval -= sop->sem_op;
curr->sempid >>= 16; /*!!!!!!*/
---------------------------------------------------------------------------
The simplest fix is just to swap the "wait for zero" condition and
PID backup, like this:
curr->sempid = (curr->sempid << 16) | pid;
if (!sem_op && curr->semval)
goto would_block;
Cheers,
Anton Lavrentiev
NCBI/NLM/NIH
Bethesda MD 20894