Avert your eyes... Arguably just the NUMA thing wouldn't be too bad. Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx> --- include/uapi/linux/futex.h | 15 ++++++++++++--- kernel/futex/futex.h | 9 ++++++++- kernel/futex/syscalls.c | 18 ++++++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) --- a/include/uapi/linux/futex.h +++ b/include/uapi/linux/futex.h @@ -23,9 +23,18 @@ #define FUTEX_CMP_REQUEUE_PI 12 #define FUTEX_LOCK_PI2 13 -#define FUTEX_PRIVATE_FLAG 128 -#define FUTEX_CLOCK_REALTIME 256 -#define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME) +#define FUTEX_PRIVATE_FLAG (1 << 7) +#define FUTEX_CLOCK_REALTIME (1 << 8) +#define FUTEX_NUMA (1 << 9) +#define FUTEX_SIZE_32 (0 << 10) /* backwards compat */ +#define FUTEX_SIZE_64 (1 << 10) +#define FUTEX_SIZE_8 (2 << 10) +#define FUTEX_SIZE_16 (3 << 10) + +#define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | \ + FUTEX_CLOCK_REALTIME | \ + FUTEX_NUMA | \ + FUTEX_SIZE_16) #define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG) #define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG) --- a/kernel/futex/futex.h +++ b/kernel/futex/futex.h @@ -39,7 +39,7 @@ /* FUTEX_ to FLAGS_ */ static inline unsigned int futex_to_flags(unsigned int op) { - unsigned int flags = FLAGS_SIZE_32; + unsigned int sz, flags = 0; if (!(op & FUTEX_PRIVATE_FLAG)) flags |= FLAGS_SHARED; @@ -47,6 +47,13 @@ static inline unsigned int futex_to_flag if (op & FUTEX_CLOCK_REALTIME) flags |= FLAGS_CLOCKRT; + if (op & FUTEX_NUMA) + flags |= FLAGS_NUMA; + + /* { 2,3,0,1 } -> { 0,1,2,3 } */ + sz = ((op + FUTEX_SIZE_8) & FUTEX_SIZE_16) >> 10; + flags |= sz; + return flags; } --- a/kernel/futex/syscalls.c +++ b/kernel/futex/syscalls.c @@ -95,6 +95,24 @@ long do_futex(u32 __user *uaddr, int op, return -ENOSYS; } + /* can't support u64 with a u32 based interface */ + if ((flags & FLAGS_SIZE_MASK) == FLAGS_SIZE_64) + return -ENOSYS; + + switch (cmd) { + case FUTEX_WAIT: + case FUTEX_WAIT_BITSET: + case FUTEX_WAKE: + case FUTEX_WAKE_BITSET: + /* u8, u16, u32 */ + break; + + default: + /* only u32 for now */ + if ((flags & FLAGS_SIZE_MASK) != FLAGS_SIZE_32) + return -ENOSYS; + } + switch (cmd) { case FUTEX_WAIT: val3 = FUTEX_BITSET_MATCH_ANY;