On Wed, 6 Feb 2019, Dmitry Safonov wrote: > #include "timekeeping.h" > #include "posix-timers.h" > @@ -1041,6 +1042,9 @@ SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, > > error = kc->clock_get(which_clock, &kernel_tp); > > + if (!error && kc->clock_timens_adjust) > + timens_clock_from_host(which_clock, &kernel_tp); Why are you adding this conditional instead of sticking the offset magic into the affected ->clock_get() implementations? That spares you the switch() and the !offsets conditional. > +static void clock_timens_fixup(int clockid, struct timespec64 *val, bool to_ns) > +{ > + struct timens_offsets *ns_offsets = current->nsproxy->time_ns->offsets; > + struct timespec64 *offsets = NULL; > + > + if (!ns_offsets) > + return; > + > + if (val->tv_sec == 0 && val->tv_nsec == 0) > + return; I have no idea why 0/0 is special. > + > + switch (clockid) { > + case CLOCK_MONOTONIC: > + case CLOCK_MONOTONIC_RAW: > + case CLOCK_MONOTONIC_COARSE: > + offsets = &ns_offsets->monotonic_time_offset; > + break; > + } > + > + if (!offsets) > + return; > + > + if (to_ns) > + *val = timespec64_add(*val, *offsets); > + else > + *val = timespec64_sub(*val, *offsets); > +} > + > +void timens_clock_to_host(int clockid, struct timespec64 *val) Does this really need to be an out of line call? If you stick this into the clock_get() implementations then it boils down to: static inline void timens_add_monotonic(struct timespec64 *ts) { struct timens_offsets *ns_offsets = current->nsproxy->time_ns->offsets; if (ns_offsets) *ts = timespec64_add(*ts, ns_offsets->monotonic_time_offset); } and static int posix_ktime_get_ts(clockid_t which_clock, struct timespec64 *tp) { ktime_get_ts64(tp); timens_add_monotonic(tp); return 0; } Hmm? Thanks, tglx