[RFC 13/20] posix-timers/timens: Take into account clock offsets
From: Dmitry Safonov <hidden>
Date: 2018-09-19 20:51:04
Also in:
lkml
Subsystem:
posix clocks and timers, the rest · Maintainers:
Anna-Maria Behnsen, Frederic Weisbecker, Thomas Gleixner, Linus Torvalds
From: Andrei Vagin <redacted> Provide a helper that will convert clocks to time namespace. Signed-off-by: Andrei Vagin <redacted> Signed-off-by: Dmitry Safonov <redacted> --- kernel/time/posix-timers.c | 52 +++++++++++++++++++++++++++++++--------------- kernel/time/posix-timers.h | 2 ++ 2 files changed, 37 insertions(+), 17 deletions(-)
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index d38835a21c5d..701cb0602b7a 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c@@ -206,12 +206,26 @@ static int posix_clock_realtime_adj(const clockid_t which_clock, return do_adjtimex(t); } -static void timens_adjust_monotonic(struct timespec64 *tp) +static void common_timens_adjust(clockid_t which_clock, struct timespec64 *tp) { struct timens_offsets *ns_offsets = current->nsproxy->time_ns->offsets; - if (ns_offsets) + if (!ns_offsets) + return; + + switch (which_clock) { + case CLOCK_MONOTONIC: + case CLOCK_MONOTONIC_RAW: + case CLOCK_MONOTONIC_COARSE: *tp = timespec64_add(*tp, ns_offsets->monotonic_time_offset); + break; + case CLOCK_BOOTTIME: + *tp = timespec64_add(*tp, ns_offsets->monotonic_boottime_offset); + break; + default: + WARN_ONCE(1, "Time Namespace offset for %d is not realized", + which_clock); + } } static int posix_ktime_set_ts(clockid_t which_clock,
@@ -239,7 +253,6 @@ static int posix_ktime_set_ts(clockid_t which_clock, static int posix_ktime_get_ts(clockid_t which_clock, struct timespec64 *tp) { ktime_get_ts64(tp); - timens_adjust_monotonic(tp); return 0; }
@@ -249,7 +262,6 @@ static int posix_ktime_get_ts(clockid_t which_clock, struct timespec64 *tp) static int posix_get_monotonic_raw(clockid_t which_clock, struct timespec64 *tp) { ktime_get_raw_ts64(tp); - timens_adjust_monotonic(tp); return 0; }
@@ -264,7 +276,6 @@ static int posix_get_monotonic_coarse(clockid_t which_clock, struct timespec64 *tp) { ktime_get_coarse_ts64(tp); - timens_adjust_monotonic(tp); return 0; }
@@ -276,15 +287,7 @@ static int posix_get_coarse_res(const clockid_t which_clock, struct timespec64 * static int posix_get_boottime(const clockid_t which_clock, struct timespec64 *tp) { - struct timens_offsets *ns_offsets = current->nsproxy->time_ns->offsets; - ktime_get_boottime_ts64(tp); - - if (!ns_offsets) - return 0; - - *tp = timespec64_add(*tp, ns_offsets->monotonic_boottime_offset); - return 0; }
@@ -933,10 +936,6 @@ static int do_timer_settime(timer_t timer_id, int flags, unsigned long flag; int error = 0; - if (!timespec64_valid(&new_spec64->it_interval) || - !timespec64_valid(&new_spec64->it_value)) - return -EINVAL; - if (old_spec64) memset(old_spec64, 0, sizeof(*old_spec64)); retry:
@@ -944,6 +943,15 @@ static int do_timer_settime(timer_t timer_id, int flags, if (!timr) return -EINVAL; + if (flags & TIMER_ABSTIME) + timens_clock_to_host(timr->it_clock, &new_spec64->it_value); + + if (!timespec64_valid(&new_spec64->it_interval) || + !timespec64_valid(&new_spec64->it_value)) { + unlock_timer(timr, flag); + return -EINVAL; + } + kc = timr->kclock; if (WARN_ON_ONCE(!kc || !kc->timer_set)) error = -EINVAL;
@@ -1121,6 +1129,9 @@ SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, error = kc->clock_get(which_clock, &kernel_tp); + if (!error && kc->clock_timens_adjust) + kc->clock_timens_adjust(which_clock, &kernel_tp); + if (!error && put_timespec64(&kernel_tp, tp)) error = -EFAULT;
@@ -1197,6 +1208,9 @@ COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock, err = kc->clock_get(which_clock, &ts); + if (!err && kc->clock_timens_adjust) + kc->clock_timens_adjust(which_clock, &ts); + if (!err && compat_put_timespec64(&ts, tp)) err = -EFAULT;
@@ -1340,6 +1354,7 @@ static const struct k_clock clock_monotonic = { .clock_getres = posix_get_hrtimer_res, .clock_get = posix_ktime_get_ts, .clock_set = posix_ktime_set_ts, + .clock_timens_adjust = common_timens_adjust, .nsleep = common_nsleep, .timer_create = common_timer_create, .timer_set = common_timer_set,
@@ -1356,6 +1371,7 @@ static const struct k_clock clock_monotonic_raw = { .clock_getres = posix_get_hrtimer_res, .clock_get = posix_get_monotonic_raw, .clock_set = posix_ktime_set_ts, + .clock_timens_adjust = common_timens_adjust, }; static const struct k_clock clock_realtime_coarse = {
@@ -1367,6 +1383,7 @@ static const struct k_clock clock_monotonic_coarse = { .clock_getres = posix_get_coarse_res, .clock_get = posix_get_monotonic_coarse, .clock_set = posix_ktime_set_ts, + .clock_timens_adjust = common_timens_adjust, }; static const struct k_clock clock_tai = {
@@ -1388,6 +1405,7 @@ static const struct k_clock clock_boottime = { .clock_getres = posix_get_hrtimer_res, .clock_get = posix_get_boottime, .clock_set = posix_set_boottime, + .clock_timens_adjust = common_timens_adjust, .nsleep = common_nsleep, .timer_create = common_timer_create, .timer_set = common_timer_set,
diff --git a/kernel/time/posix-timers.h b/kernel/time/posix-timers.h
index ddb21145211a..308774bea32a 100644
--- a/kernel/time/posix-timers.h
+++ b/kernel/time/posix-timers.h@@ -8,6 +8,8 @@ struct k_clock { const struct timespec64 *tp); int (*clock_get)(const clockid_t which_clock, struct timespec64 *tp); + void (*clock_timens_adjust)(const clockid_t which_clock, + struct timespec64 *tp); int (*clock_adj)(const clockid_t which_clock, struct timex *tx); int (*timer_create)(struct k_itimer *timer); int (*nsleep)(const clockid_t which_clock, int flags,
--
2.13.6