Commit ea2d1f7f authored by Andrei Vagin's avatar Andrei Vagin Committed by Thomas Gleixner

hrtimers: Prepare hrtimer_nanosleep() for time namespaces

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: default avatarDmitry Safonov <dima@arista.com>
Signed-off-by: default avatarAndrei Vagin <avagin@openvz.org>
Signed-off-by: default avatarDmitry Safonov <dima@arista.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20191112012724.250792-17-dima@arista.com
parent 0b9b9a3b
...@@ -508,8 +508,7 @@ static inline u64 hrtimer_forward_now(struct hrtimer *timer, ...@@ -508,8 +508,7 @@ static inline u64 hrtimer_forward_now(struct hrtimer *timer,
/* Precise sleep: */ /* Precise sleep: */
extern int nanosleep_copyout(struct restart_block *, struct timespec64 *); extern int nanosleep_copyout(struct restart_block *, struct timespec64 *);
extern long hrtimer_nanosleep(const struct timespec64 *rqtp, extern long hrtimer_nanosleep(ktime_t rqtp, const enum hrtimer_mode mode,
const enum hrtimer_mode mode,
const clockid_t clockid); const clockid_t clockid);
extern int schedule_hrtimeout_range(ktime_t *expires, u64 delta, extern int schedule_hrtimeout_range(ktime_t *expires, u64 delta,
......
...@@ -1910,8 +1910,8 @@ static long __sched hrtimer_nanosleep_restart(struct restart_block *restart) ...@@ -1910,8 +1910,8 @@ static long __sched hrtimer_nanosleep_restart(struct restart_block *restart)
return ret; return ret;
} }
long hrtimer_nanosleep(const struct timespec64 *rqtp, long hrtimer_nanosleep(ktime_t rqtp, const enum hrtimer_mode mode,
const enum hrtimer_mode mode, const clockid_t clockid) const clockid_t clockid)
{ {
struct restart_block *restart; struct restart_block *restart;
struct hrtimer_sleeper t; struct hrtimer_sleeper t;
...@@ -1923,7 +1923,7 @@ long hrtimer_nanosleep(const struct timespec64 *rqtp, ...@@ -1923,7 +1923,7 @@ long hrtimer_nanosleep(const struct timespec64 *rqtp,
slack = 0; slack = 0;
hrtimer_init_sleeper_on_stack(&t, clockid, mode); 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); ret = do_nanosleep(&t, mode);
if (ret != -ERESTART_RESTARTBLOCK) if (ret != -ERESTART_RESTARTBLOCK)
goto out; goto out;
...@@ -1958,7 +1958,8 @@ SYSCALL_DEFINE2(nanosleep, struct __kernel_timespec __user *, rqtp, ...@@ -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.type = rmtp ? TT_NATIVE : TT_NONE;
current->restart_block.nanosleep.rmtp = rmtp; 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 #endif
...@@ -1978,7 +1979,8 @@ SYSCALL_DEFINE2(nanosleep_time32, struct old_timespec32 __user *, rqtp, ...@@ -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.type = rmtp ? TT_COMPAT : TT_NONE;
current->restart_block.nanosleep.compat_rmtp = rmtp; 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 #endif
......
...@@ -147,7 +147,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, ...@@ -147,7 +147,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
rmtp = NULL; rmtp = NULL;
current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE;
current->restart_block.nanosleep.rmtp = rmtp; 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, HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
which_clock); which_clock);
} }
...@@ -236,7 +236,7 @@ SYSCALL_DEFINE4(clock_nanosleep_time32, clockid_t, which_clock, int, flags, ...@@ -236,7 +236,7 @@ SYSCALL_DEFINE4(clock_nanosleep_time32, clockid_t, which_clock, int, flags,
rmtp = NULL; rmtp = NULL;
current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE;
current->restart_block.nanosleep.compat_rmtp = rmtp; 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, HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
which_clock); which_clock);
} }
......
...@@ -1221,7 +1221,9 @@ SYSCALL_DEFINE2(clock_getres_time32, clockid_t, which_clock, ...@@ -1221,7 +1221,9 @@ SYSCALL_DEFINE2(clock_getres_time32, clockid_t, which_clock,
static int common_nsleep(const clockid_t which_clock, int flags, static int common_nsleep(const clockid_t which_clock, int flags,
const struct timespec64 *rqtp) 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, HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
which_clock); which_clock);
} }
......
...@@ -41,9 +41,11 @@ ...@@ -41,9 +41,11 @@
#include <bpf.h> #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); license(GPL);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment