summaryrefslogtreecommitdiffstats
path: root/drivers/hv
diff options
context:
space:
mode:
authorAlex Ng <alexng@messages.microsoft.com>2016-09-08 08:24:13 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-09-08 07:53:07 -0400
commit2e338f7e034f12066c78999deff8894c337ae23b (patch)
treebf1d0cb3c03de107ae0a147c937c856159e1cdfe /drivers/hv
parentabeda47ebb20997aa3c5b4cac7db70f8bea62d7d (diff)
Drivers: hv: utils: Use TimeSync samples to adjust the clock after boot.
Only the first 50 samples after boot were being used to discipline the clock. After the first 50 samples, any samples from the host were ignored and the guest clock would eventually drift from the host clock. This patch allows TimeSync-enabled guests to continuously synchronize the clock with the host clock, even after the first 50 samples. Signed-off-by: Alex Ng <alexng@messages.microsoft.com> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv')
-rw-r--r--drivers/hv/hv_util.c20
1 files changed, 7 insertions, 13 deletions
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
index b27a8ee3de57..4002b717c777 100644
--- a/drivers/hv/hv_util.c
+++ b/drivers/hv/hv_util.c
@@ -198,29 +198,23 @@ static void hv_set_host_time(struct work_struct *work)
198 * ICTIMESYNCFLAG_SYNC flag bit indicates reboot, restore events of the VM. 198 * ICTIMESYNCFLAG_SYNC flag bit indicates reboot, restore events of the VM.
199 * After reboot the flag ICTIMESYNCFLAG_SYNC is included in the first time 199 * After reboot the flag ICTIMESYNCFLAG_SYNC is included in the first time
200 * message after the timesync channel is opened. Since the hv_utils module is 200 * message after the timesync channel is opened. Since the hv_utils module is
201 * loaded after hv_vmbus, the first message is usually missed. The other 201 * loaded after hv_vmbus, the first message is usually missed. This bit is
202 * thing is, systime is automatically set to emulated hardware clock which may 202 * considered a hard request to discipline the clock.
203 * not be UTC time or in the same time zone. So, to override these effects, we 203 *
204 * use the first 50 time samples for initial system time setting. 204 * ICTIMESYNCFLAG_SAMPLE bit indicates a time sample from host. This is
205 * typically used as a hint to the guest. The guest is under no obligation
206 * to discipline the clock.
205 */ 207 */
206static inline void adj_guesttime(u64 hosttime, u8 flags) 208static inline void adj_guesttime(u64 hosttime, u8 flags)
207{ 209{
208 struct adj_time_work *wrk; 210 struct adj_time_work *wrk;
209 static s32 scnt = 50;
210 211
211 wrk = kmalloc(sizeof(struct adj_time_work), GFP_ATOMIC); 212 wrk = kmalloc(sizeof(struct adj_time_work), GFP_ATOMIC);
212 if (wrk == NULL) 213 if (wrk == NULL)
213 return; 214 return;
214 215
215 wrk->host_time = hosttime; 216 wrk->host_time = hosttime;
216 if ((flags & ICTIMESYNCFLAG_SYNC) != 0) { 217 if ((flags & (ICTIMESYNCFLAG_SYNC | ICTIMESYNCFLAG_SAMPLE)) != 0) {
217 INIT_WORK(&wrk->work, hv_set_host_time);
218 schedule_work(&wrk->work);
219 return;
220 }
221
222 if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && scnt > 0) {
223 scnt--;
224 INIT_WORK(&wrk->work, hv_set_host_time); 218 INIT_WORK(&wrk->work, hv_set_host_time);
225 schedule_work(&wrk->work); 219 schedule_work(&wrk->work);
226 } else 220 } else