Comments from Davidlohr:
So there are two things here regarding ordering. One is the
most obvious which is ordered due to the taking/dropping the
hb spinlock. Secondly, its the cases which Peter brought up
a while ago that involves atomic futex ops futex_atomic_*(),
which do not have clearly defined semantics, and you get
inconsistencies with certain archs (tile being the worst
iirc).
But anyway, the important thing users need to know about is
that the atomic futex operation must be totally ordered wrt
any other user tasks that are trying to access that address.
This is not necessarily the case for kernel ops. Peter
illustrates this nicely with lock stealing example; (see
https://lkml.org/lkml/2015/8/26/596).
Internally, I believe we decided that making it fully ordered
(as opposed to making use of implicit barriers for
ACQUIRE/RELEASE), so you'd end up having an MB ll/sc MB kind of
setup.
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
Reported-by: Davidlohr Bueso <dave@stgolabs.net>
Darren Hart pointed me to the comments from Rich Felker
that there are valid use cases for FUTEX_REQUEUE.
From: Rich Felker <dalias@libc.org>
Date: Wed, 29 Oct 2014 22:43:17 -0400
To: Darren Hart <dvhart@infradead.org>
Cc: GLIBC Devel <libc-alpha@sourceware.org>, ...
Subject: Re: Add futex wrapper to glibc?
On Wed, Oct 29, 2014 at 06:59:15PM -0700, Darren Hart wrote:
[...]
> I wonder though... can we not wrap FUTEX_REQUEUE? It's fundamentally
> broken. FUTEX_CMP_REQUEUE should *always* be used instead. The glibc
> wrapper is one way to encourage developers to do the right thing
> (don't expose the bad op in the header).
You're mistaken here. There are plenty of valid ways to use
FUTEX_REQUEUE - for example if the calling thread is requeuing the
target(s) to a lock that the calling thread owns. Just because it
doesn't meet the needs of the way glibc was using it internally
doesn't mean it's useless for other applications.
Reported-by: Darren Hart <dvhart@infradead.org>
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
As commented on by Davidlohr Bueso:
This to me reads a bit too much into the kernel (fastpath,
refcnt, vmas). Why not just mention that it avoids overhead
in the kernel or something? I don't recall any manpage
mentioning such details, but I could be wrong.
Reported-by: Davidlohr Bueso <dave@stgolabs.net>
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
The kernel uses the following cast:
if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE ||
cmd == FUTEX_CMP_REQUEUE_PI || cmd == FUTEX_WAKE_OP)
val2 = (u32) (unsigned long) utime;
This ensures that always the least significant four bytes of the
pointer are used, both on ILP32 and LP64 systems.
On a big endian system a simple cast from 64 bit pointer to 32 bit
integer would return the most significant four bytes.
We have to make the reader of the man-page aware of the usage
of the least significant bytes.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
Type u32 is not exposed to the user. Instead, refer to uint32_t,
which is defined in ISO/IEC 9899:1999.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>