This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
Home Products Support Community News


[Xen-devel] [PATCH] xen pmtimer: correct pmtimer accuracy

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] xen pmtimer: correct pmtimer accuracy
From: Andrew Jones <drjones@xxxxxxxxxx>
Date: Thu, 16 Sep 2010 13:47:58 +0200
Cc: uobergfe@xxxxxxxxxx
Delivery-date: Thu, 16 Sep 2010 04:50:13 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
From: Ulrich Obergfell <uobergfe@xxxxxxxxxx>

Several seconds of backward time drift per minute can be seen on a
RHEL6 HVM guest by switching the clocksource to 'acpi_pm' and then
running gettimeofday() in a loop. This is due to the accumulation
of small inaccuracies that are caused by shifting out the lower 32
bits when pmt_update_time() computes 'tmr_val'.

The patch makes sure that the lower 32 bits of the computed value
are not lost. They are saved in a new field 'not_accounted' in the
PMTState structure and are accounted the next time pmt_update_time()
is called.

diff --git a/xen/arch/x86/hvm/pmtimer.c b/xen/arch/x86/hvm/pmtimer.c
--- a/xen/arch/x86/hvm/pmtimer.c
+++ b/xen/arch/x86/hvm/pmtimer.c
@@ -84,13 +84,16 @@
 static void pmt_update_time(PMTState *s)
     uint64_t curr_gtime;
+    uint64_t tmp;
     uint32_t msb = s->pm.tmr_val & TMR_VAL_MSB;
     /* Update the timer */
     curr_gtime = hvm_get_guest_time(s->vcpu);
-    s->pm.tmr_val += ((curr_gtime - s->last_gtime) * s->scale) >> 32;
+    tmp = ((curr_gtime - s->last_gtime) * s->scale) + s->not_accounted;
+    s->not_accounted = tmp & 0xffffffff;
+    s->pm.tmr_val += tmp >> 32;
     s->pm.tmr_val &= TMR_VAL_MASK;
     s->last_gtime = curr_gtime;
@@ -276,6 +279,7 @@
     s->scale = ((uint64_t)FREQUENCE_PMTIMER << 32) / SYSTEM_TIME_HZ;
+    s->not_accounted = 0;
     s->vcpu = v;
     /* Intercept port I/O (need two handlers because PM1a_CNT is between
diff --git a/xen/include/asm-x86/hvm/vpt.h b/xen/include/asm-x86/hvm/vpt.h
--- a/xen/include/asm-x86/hvm/vpt.h
+++ b/xen/include/asm-x86/hvm/vpt.h
@@ -117,6 +117,7 @@
     struct hvm_hw_pmtimer pm;   /* 32bit timer value */
     struct vcpu *vcpu;          /* Keeps sync with this vcpu's guest-time */
     uint64_t last_gtime;        /* Last (guest) time we updated the timer */
+    uint64_t not_accounted;     /* time not accounted at last update */
     uint64_t scale;             /* Multiplier to get from tsc to timer ticks */
     struct timer timer;         /* To make sure we send SCIs */
     spinlock_t lock;

Xen-devel mailing list

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] xen pmtimer: correct pmtimer accuracy, Andrew Jones <=