Skip to content

Commit 51cf94d

Browse files
committed
futex: Make syscall entry points less convoluted
The futex and the compat syscall entry points do pretty much the same except for the timespec data types and the corresponding copy from user function. Split out the rest into inline functions and share the functionality. Signed-off-by: Thomas Gleixner <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent b097d5e commit 51cf94d

File tree

1 file changed

+37
-26
lines changed

1 file changed

+37
-26
lines changed

kernel/futex.c

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3757,30 +3757,48 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
37573757
return -ENOSYS;
37583758
}
37593759

3760+
static __always_inline bool futex_cmd_has_timeout(u32 cmd)
3761+
{
3762+
switch (cmd) {
3763+
case FUTEX_WAIT:
3764+
case FUTEX_LOCK_PI:
3765+
case FUTEX_WAIT_BITSET:
3766+
case FUTEX_WAIT_REQUEUE_PI:
3767+
return true;
3768+
}
3769+
return false;
3770+
}
3771+
3772+
static __always_inline int
3773+
futex_init_timeout(u32 cmd, u32 op, struct timespec64 *ts, ktime_t *t)
3774+
{
3775+
if (!timespec64_valid(ts))
3776+
return -EINVAL;
3777+
3778+
*t = timespec64_to_ktime(*ts);
3779+
if (cmd == FUTEX_WAIT)
3780+
*t = ktime_add_safe(ktime_get(), *t);
3781+
else if (cmd != FUTEX_LOCK_PI && !(op & FUTEX_CLOCK_REALTIME))
3782+
*t = timens_ktime_to_host(CLOCK_MONOTONIC, *t);
3783+
return 0;
3784+
}
37603785

37613786
SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,
37623787
const struct __kernel_timespec __user *, utime,
37633788
u32 __user *, uaddr2, u32, val3)
37643789
{
3765-
struct timespec64 ts;
3790+
int ret, cmd = op & FUTEX_CMD_MASK;
37663791
ktime_t t, *tp = NULL;
3767-
int cmd = op & FUTEX_CMD_MASK;
3792+
struct timespec64 ts;
37683793

3769-
if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI ||
3770-
cmd == FUTEX_WAIT_BITSET ||
3771-
cmd == FUTEX_WAIT_REQUEUE_PI)) {
3794+
if (utime && futex_cmd_has_timeout(cmd)) {
37723795
if (unlikely(should_fail_futex(!(op & FUTEX_PRIVATE_FLAG))))
37733796
return -EFAULT;
37743797
if (get_timespec64(&ts, utime))
37753798
return -EFAULT;
3776-
if (!timespec64_valid(&ts))
3777-
return -EINVAL;
3778-
3779-
t = timespec64_to_ktime(ts);
3780-
if (cmd == FUTEX_WAIT)
3781-
t = ktime_add_safe(ktime_get(), t);
3782-
else if (cmd != FUTEX_LOCK_PI && !(op & FUTEX_CLOCK_REALTIME))
3783-
t = timens_ktime_to_host(CLOCK_MONOTONIC, t);
3799+
ret = futex_init_timeout(cmd, op, &ts, &t);
3800+
if (ret)
3801+
return ret;
37843802
tp = &t;
37853803
}
37863804

@@ -3950,23 +3968,16 @@ SYSCALL_DEFINE6(futex_time32, u32 __user *, uaddr, int, op, u32, val,
39503968
const struct old_timespec32 __user *, utime, u32 __user *, uaddr2,
39513969
u32, val3)
39523970
{
3953-
struct timespec64 ts;
3971+
int ret, cmd = op & FUTEX_CMD_MASK;
39543972
ktime_t t, *tp = NULL;
3955-
int cmd = op & FUTEX_CMD_MASK;
3973+
struct timespec64 ts;
39563974

3957-
if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI ||
3958-
cmd == FUTEX_WAIT_BITSET ||
3959-
cmd == FUTEX_WAIT_REQUEUE_PI)) {
3975+
if (utime && futex_cmd_has_timeout(cmd)) {
39603976
if (get_old_timespec32(&ts, utime))
39613977
return -EFAULT;
3962-
if (!timespec64_valid(&ts))
3963-
return -EINVAL;
3964-
3965-
t = timespec64_to_ktime(ts);
3966-
if (cmd == FUTEX_WAIT)
3967-
t = ktime_add_safe(ktime_get(), t);
3968-
else if (cmd != FUTEX_LOCK_PI && !(op & FUTEX_CLOCK_REALTIME))
3969-
t = timens_ktime_to_host(CLOCK_MONOTONIC, t);
3978+
ret = futex_init_timeout(cmd, op, &ts, &t);
3979+
if (ret)
3980+
return ret;
39703981
tp = &t;
39713982
}
39723983

0 commit comments

Comments
 (0)