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: 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
This commit is contained in:

committed by
Thomas Gleixner

parent
0b9b9a3b16
commit
ea2d1f7fce
@@ -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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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 @@
|
|||||||
|
|
||||||
#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);
|
||||||
|
Reference in New Issue
Block a user