Stephen Hemminger <stephen@xxxxxxxxxxxxxxxxxx> writes: > 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. I see. While s64 should work ktime seems preferable. I'll give it a try. -- Vitaly _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel