Messages in this thread | | | Subject | race condition in down_interruptible | Date | Fri, 12 Feb 1999 16:21:05 +0100 | From | Ulrich Schmid <> |
| |
Hi,
when I had a look at down_interruptible(), I suspect that there could be a race condition:
sem->count sem->waking No process holds the semaphore 1 0 Process A acquires the semaphore 0 0 Process B calls down_interruptible() -1 0 Process B is interrupted and passes waking_non_zero() -1 0 Process A calls up() (on another CPU) 0 1 Process B calls atomic_inc(&sem->count) 1 1 !! No process is waiting, but sem->waking > 0 !! Process C acquires the semaphore 0 1 Process D calls down() -1 1 Process D passes waking_non_zero() and acquires the semaphore !! -1 0
My suggestion is to replace in DOWN_TAIL() atomic_inc(&sem->count); by wake_one_less(sem); up(sem); [wake_one_less() would be defined analogous to wake_one_more()]
The difference is, that the up() call will take care about the special condition if sem->count is already zero before it is increased.
This solution would allow sem->waking to be temporarily negative, in which case waking_non_zero() must not allow processes to wake up. For most but not all of the architectures waking_non_zero() is already implemented this way. To make this requirement clearer, waking_non_zero() should be renamed to waking_positive()
--
Further I would like to suggest a nonblocking down operation down_nonblocking() analogous to down_interruptible(). I am working on a device driver and want to protect resources with semaphores, while still honoring O_NONBLOCK. For such a case a nonblocking down operation would be very helpful.
--
I don't attach patches because they would affect architecture specific code for all architectures, but I would not be able to test them all. I'm willing to submit the (partly untested) diffs on demand.
Ulrich Schmid, uschmid@mail.hh.provi.de
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |