lkml.org 
[lkml]   [2021]   [Apr]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 6/6] futex: Provide FUTEX_LOCK_PI2 to support clock selection
    The FUTEX_LOCK_PI futex operand uses a CLOCK_REALTIME based absolute
    timeout since it was implemented, but it does not require that the
    FUTEX_CLOCK_REALTIME flag is set, because that was introduced later.

    In theory as none of the user space implementations can set the
    FUTEX_CLOCK_REALTIME flag on this operand, it would be possible to
    creatively abuse it and make the meaning invers, i.e. select CLOCK_REALTIME
    when not set and CLOCK_MONOTONIC when set. But that's a nasty hackery.

    Another option would be to have a new FUTEX_CLOCK_MONOTONIC flag only for
    FUTEX_LOCK_PI, but that's also awkward because it does not allow libraries
    to handle the timeout clock selection consistently.

    So provide a new FUTEX_LOCK_PI2 operand which implements the timeout
    semantics which the other operands use and leave FUTEX_LOCK_PI alone.

    Reported-by: Kurt Kanzenbach <kurt@linutronix.de>
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    ---
    include/uapi/linux/futex.h | 1 +
    kernel/futex.c | 6 +++++-
    2 files changed, 6 insertions(+), 1 deletion(-)

    --- a/include/uapi/linux/futex.h
    +++ b/include/uapi/linux/futex.h
    @@ -21,6 +21,7 @@
    #define FUTEX_WAKE_BITSET 10
    #define FUTEX_WAIT_REQUEUE_PI 11
    #define FUTEX_CMP_REQUEUE_PI 12
    +#define FUTEX_LOCK_PI2 13

    #define FUTEX_PRIVATE_FLAG 128
    #define FUTEX_CLOCK_REALTIME 256
    --- a/kernel/futex.c
    +++ b/kernel/futex.c
    @@ -3711,7 +3711,8 @@ long do_futex(u32 __user *uaddr, int op,

    if (op & FUTEX_CLOCK_REALTIME) {
    flags |= FLAGS_CLOCKRT;
    - if (cmd != FUTEX_WAIT_BITSET && cmd != FUTEX_WAIT_REQUEUE_PI)
    + if (cmd != FUTEX_WAIT_BITSET && cmd != FUTEX_WAIT_REQUEUE_PI &&
    + cmd != FUTEX_LOCK_PI2)
    return -ENOSYS;
    }

    @@ -3744,6 +3745,8 @@ long do_futex(u32 __user *uaddr, int op,
    return futex_wake_op(uaddr, flags, uaddr2, val, val2, val3);
    case FUTEX_LOCK_PI:
    flags |= FLAGS_CLOCKRT;
    + fallthrough;
    + case FUTEX_LOCK_PI2:
    return futex_lock_pi(uaddr, flags, timeout, 0);
    case FUTEX_UNLOCK_PI:
    return futex_unlock_pi(uaddr, flags);
    @@ -3764,6 +3767,7 @@ static inline bool futex_cmd_has_timeout
    switch (cmd) {
    case FUTEX_WAIT:
    case FUTEX_LOCK_PI:
    + case FUTEX_LOCK_PI2:
    case FUTEX_WAIT_BITSET:
    case FUTEX_WAIT_REQUEUE_PI:
    return true;
    \
     
     \ /
      Last update: 2021-04-22 22:30    [W:4.320 / U:0.040 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site