Re: Futex queue_me/get_user ordering (was: 2.6.10-rc1-mm5 [u])

From: Jamie Lokier
Date: Mon Nov 15 2004 - 03:10:22 EST

Chuck Ebbert wrote:
> On Sun, 14 Nov 2004 at 09:00:23 +0000 Emergency Services Jamie Lokier wrote:
> >+ * The basic logical guarantee of a futex is that it blocks ONLY
> >+ * if cond(var) is known to be true at the time of blocking, for
> >+ * any cond. If we queued after testing *uaddr, that would open
> >+ * a race condition where we could block indefinitely with
> >+ * cond(var) false, which would violate the guarantee.
> >+ *
> >+ * A consequence is that futex_wait() can return zero and absorb
> >+ * a wakeup when *uaddr != val on entry to the syscall. This is
> >+ * rare, but normal.
> Why can't it absorb a wakeup and still return -EAGAIN when this happens?
> IOW why not apply this patch to the original code?
> out_unqueue:
> - /* If we were woken (and unqueued), we succeeded, whatever. */
> - if (!unqueue_me(&q))
> - ret = 0;
> + unqueue_me(&q); /* ignore result from unqueue */
> out_release_sem:
> up_read(&current->mm->mmap_sem);
> return ret;

Because the number of wakeups reported to FUTEX_WAKE must _exactly_
match the number of wakeups reported to FUTEX_WAIT.

They are like tokens, and for some data structures the return value
mustn't be lost or ignored, because that would break structure
invariants - such as the matching counters in the pthread condvars
which precipitated this thread.

> ...and what is "Emergency Services", BTW?

My little joke, as I wouldn't have known about this if Andrew Morton
hadn't forwarded me the message asking about it (I've been away from l-k).

-- Jamie
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at
Please read the FAQ at