hrtimers: Prepare hrtimer_nanosleep() for time namespaces
authorAndrei Vagin <avagin@gmail.com>
Tue, 12 Nov 2019 01:27:05 +0000 (01:27 +0000)
committerThomas Gleixner <tglx@linutronix.de>
Tue, 14 Jan 2020 11:20:55 +0000 (12:20 +0100)
clock_nanosleep() accepts absolute values of expiration time when
TIMER_ABSTIME flag is set. This absolute value is inside the task's
time namespace, and has to be converted to the host's time.

There is timens_ktime_to_host() helper for converting time, but
it accepts ktime argument.

As a preparation, make hrtimer_nanosleep() accept a clock value in ktime
instead of timespec64.

Co-developed-by: Dmitry Safonov <dima@arista.com>
Signed-off-by: Andrei Vagin <avagin@openvz.org>
Signed-off-by: Dmitry Safonov <dima@arista.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20191112012724.250792-17-dima@arista.com
include/linux/hrtimer.h
kernel/time/hrtimer.c
kernel/time/posix-stubs.c
kernel/time/posix-timers.c
tools/perf/examples/bpf/5sec.c

index 1f98b52118f0a31541f3ce6f2cb52520442b778b..15c8ac3136780fdc177fbc6f7c7342dfd79fcdcb 100644 (file)
@@ -508,8 +508,7 @@ static inline u64 hrtimer_forward_now(struct hrtimer *timer,
 /* Precise sleep: */
 
 extern int nanosleep_copyout(struct restart_block *, struct timespec64 *);
-extern long hrtimer_nanosleep(const struct timespec64 *rqtp,
-                             const enum hrtimer_mode mode,
+extern long hrtimer_nanosleep(ktime_t rqtp, const enum hrtimer_mode mode,
                              const clockid_t clockid);
 
 extern int schedule_hrtimeout_range(ktime_t *expires, u64 delta,
index 8de90ea31280bfd4986534dc03dcf5bcfeee5a75..d8b62f93fc8dcb6ad2b699c0ca8949ed25a1315b 100644 (file)
@@ -1910,8 +1910,8 @@ static long __sched hrtimer_nanosleep_restart(struct restart_block *restart)
        return ret;
 }
 
-long hrtimer_nanosleep(const struct timespec64 *rqtp,
-                      const enum hrtimer_mode mode, const clockid_t clockid)
+long hrtimer_nanosleep(ktime_t rqtp, const enum hrtimer_mode mode,
+                      const clockid_t clockid)
 {
        struct restart_block *restart;
        struct hrtimer_sleeper t;
@@ -1923,7 +1923,7 @@ long hrtimer_nanosleep(const struct timespec64 *rqtp,
                slack = 0;
 
        hrtimer_init_sleeper_on_stack(&t, clockid, mode);
-       hrtimer_set_expires_range_ns(&t.timer, timespec64_to_ktime(*rqtp), slack);
+       hrtimer_set_expires_range_ns(&t.timer, rqtp, slack);
        ret = do_nanosleep(&t, mode);
        if (ret != -ERESTART_RESTARTBLOCK)
                goto out;
@@ -1958,7 +1958,8 @@ SYSCALL_DEFINE2(nanosleep, struct __kernel_timespec __user *, rqtp,
 
        current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE;
        current->restart_block.nanosleep.rmtp = rmtp;
-       return hrtimer_nanosleep(&tu, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
+       return hrtimer_nanosleep(timespec64_to_ktime(tu), HRTIMER_MODE_REL,
+                                CLOCK_MONOTONIC);
 }
 
 #endif
@@ -1978,7 +1979,8 @@ SYSCALL_DEFINE2(nanosleep_time32, struct old_timespec32 __user *, rqtp,
 
        current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE;
        current->restart_block.nanosleep.compat_rmtp = rmtp;
-       return hrtimer_nanosleep(&tu, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
+       return hrtimer_nanosleep(timespec64_to_ktime(tu), HRTIMER_MODE_REL,
+                                CLOCK_MONOTONIC);
 }
 #endif
 
index bcbaa2045f5e8027129cc174033e8fe0304f1aa3..5745a138f254e7b67868e59d2cfde486523a7e28 100644 (file)
@@ -147,7 +147,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
                rmtp = NULL;
        current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE;
        current->restart_block.nanosleep.rmtp = rmtp;
-       return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ?
+       return hrtimer_nanosleep(timespec64_to_ktime(t), flags & TIMER_ABSTIME ?
                                 HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
                                 which_clock);
 }
@@ -236,7 +236,7 @@ SYSCALL_DEFINE4(clock_nanosleep_time32, clockid_t, which_clock, int, flags,
                rmtp = NULL;
        current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE;
        current->restart_block.nanosleep.compat_rmtp = rmtp;
-       return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ?
+       return hrtimer_nanosleep(timespec64_to_ktime(t), flags & TIMER_ABSTIME ?
                                 HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
                                 which_clock);
 }
index 473082b0b57fdc12403ce80b9a3b0adfe055244e..75fee6e39e5ab0e3c9835316faf5298b328b03f0 100644 (file)
@@ -1221,7 +1221,9 @@ SYSCALL_DEFINE2(clock_getres_time32, clockid_t, which_clock,
 static int common_nsleep(const clockid_t which_clock, int flags,
                         const struct timespec64 *rqtp)
 {
-       return hrtimer_nanosleep(rqtp, flags & TIMER_ABSTIME ?
+       ktime_t texp = timespec64_to_ktime(*rqtp);
+
+       return hrtimer_nanosleep(texp, flags & TIMER_ABSTIME ?
                                 HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
                                 which_clock);
 }
index b9c203219691a4758eff6578bd00ee7c09bec10b..e6b6181c6dc63b29abf7463c7bee52c048e5e112 100644 (file)
 
 #include <bpf.h>
 
-int probe(hrtimer_nanosleep, rqtp->tv_sec)(void *ctx, int err, long sec)
+#define NSEC_PER_SEC   1000000000L
+
+int probe(hrtimer_nanosleep, rqtp)(void *ctx, int err, long long sec)
 {
-       return sec == 5;
+       return sec / NSEC_PER_SEC == 5ULL;
 }
 
 license(GPL);