On Wed, 4 Jan 2017 18:24:38 +0100 Vitaly Kuznetsov <vkuznets@xxxxxxxxxx> wrote: > With TimeSync version 4 protocol support we started updating system time > continuously through the whole lifetime of Hyper-V guests. Every 5 seconds > there is a time sample from the host which triggers do_settimeofday[64](). > While the time from the host is very accurate such adjustments may cause > issues: > - Time is jumping forward and backward, some applications may misbehave. > - In case an NTP client is run in parallel things may go south, e.g. when > an NTP client tries to adjust tick/frequency with ADJ_TICK/ADJ_FREQUENCY > the Hyper-V module will not see this changes and time will oscillate and > never converge. > - Systemd starts annoying you by printing "Time has been changed" every 5 > seconds to the system log. > > Instead of calling do_settimeofday64() we can pretend being an NTP client > and use do_adjtimex(). Do do_settimeofday64() in case the difference is too > big or ICTIMESYNCFLAG_SYNC flag was set in the request. > > Signed-off-by: Vitaly Kuznetsov <vkuznets@xxxxxxxxxx> > --- > Changes since v1: > - do do_settimeofday64() when ICTIMESYNCFLAG_SYNC flag is present in the > request (Alex Ng) > - add pr_debug() for the case when do_adjtimex() fails (Alex Ng) > --- > drivers/hv/hv_util.c | 32 +++++++++++++++++++++++++++++--- > 1 file changed, 29 insertions(+), 3 deletions(-) > > diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c > index 94719eb..7e97231 100644 > --- a/drivers/hv/hv_util.c > +++ b/drivers/hv/hv_util.c > @@ -182,9 +182,11 @@ struct adj_time_work { > static void hv_set_host_time(struct work_struct *work) > { > struct adj_time_work *wrk; > - s64 host_tns; > + s64 host_tns, our_tns, delta; > u64 newtime; > - struct timespec64 host_ts; > + struct timespec64 host_ts, our_ts; > + struct timex txc = {0}; > + int ret; > > wrk = container_of(work, struct adj_time_work, work); > > @@ -205,7 +207,31 @@ static void hv_set_host_time(struct work_struct *work) > host_tns = (newtime - WLTIMEDELTA) * 100; > host_ts = ns_to_timespec64(host_tns); > > - do_settimeofday64(&host_ts); > + getnstimeofday64(&our_ts); > + our_tns = timespec64_to_ns(&our_ts); > + > + /* Difference between our time and host time */ > + delta = host_tns - our_tns; This looks correct to me. Did you consider using ktime? It provides a cleaner abstraction for handling nanosecond time resolution. _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel