[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Some time-handling fixes.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1265624088 0
# Node ID f330b15f885ded7ee26594bd8ab27e206e2cb4cc
# Parent  5e49312fcb4465ec6715e204b6a50b0f06abf1c2
Some time-handling fixes.

Fixes my domU boot hangs (when using vtsc) due to vtsc_offset less
then local cpu's stime_local_stamp, leading to bogus
vcpu_time_info.tsc_timestamp.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/time.c |   40 ++++++++++++++++++++++++++++------------
 1 files changed, 28 insertions(+), 12 deletions(-)

diff -r 5e49312fcb44 -r f330b15f885d xen/arch/x86/time.c
--- a/xen/arch/x86/time.c       Mon Feb 08 08:50:03 2010 +0000
+++ b/xen/arch/x86/time.c       Mon Feb 08 10:14:48 2010 +0000
@@ -827,14 +827,14 @@ static void __update_vcpu_system_time(st
     u = &vcpu_info(v, time);
 
     if ( d->arch.vtsc )
-        tsc_stamp = scale_delta(t->stime_local_stamp - d->arch.vtsc_offset,
-                                &d->arch.ns_to_vtsc);
+    {
+        u64 delta = max_t(s64, t->stime_local_stamp - d->arch.vtsc_offset, 0);
+        tsc_stamp = scale_delta(delta, &d->arch.ns_to_vtsc);
+    }
     else
+    {
         tsc_stamp = t->local_tsc_stamp;
-
-    /* Don't bother unless timestamps have changed or we are forced. */
-    if ( !force && (u->tsc_timestamp == tsc_stamp) )
-        return;
+    }
 
     memset(&_u, 0, sizeof(_u));
 
@@ -852,6 +852,11 @@ static void __update_vcpu_system_time(st
         _u.tsc_to_system_mul = t->tsc_scale.mul_frac;
         _u.tsc_shift         = (s8)t->tsc_scale.shift;
     }
+
+    /* Don't bother unless timestamp record has changed or we are forced. */
+    _u.version = u->version; /* make versions match for memcmp test */
+    if ( !force && !memcmp(u, &_u, sizeof(_u)) )
+        return;
 
     /* 1. Update guest kernel version. */
     _u.version = u->version = version_update_begin(u->version);
@@ -1617,6 +1622,7 @@ void pv_soft_rdtsc(struct vcpu *v, struc
 {
     s_time_t now = get_s_time();
     struct domain *d = v->domain;
+    u64 delta;
 
     spin_lock(&d->arch.vtsc_lock);
 
@@ -1632,7 +1638,8 @@ void pv_soft_rdtsc(struct vcpu *v, struc
 
     spin_unlock(&d->arch.vtsc_lock);
 
-    now = scale_delta(now - d->arch.vtsc_offset, &d->arch.ns_to_vtsc);
+    delta = max_t(s64, now - d->arch.vtsc_offset, 0);
+    now = scale_delta(delta, &d->arch.ns_to_vtsc);
 
     regs->eax = (uint32_t)now;
     regs->edx = (uint32_t)(now >> 32);
@@ -1693,7 +1700,9 @@ void tsc_get_info(struct domain *d, uint
                   uint32_t *incarnation)
 {
     *incarnation = d->arch.incarnation;
-    switch ( *tsc_mode = d->arch.tsc_mode )
+    *tsc_mode = d->arch.tsc_mode;
+
+    switch ( *tsc_mode )
     {
     case TSC_MODE_NEVER_EMULATE:
         *elapsed_nsec =  *gtsc_khz = 0;
@@ -1707,7 +1716,9 @@ void tsc_get_info(struct domain *d, uint
         {
             *elapsed_nsec = get_s_time() - d->arch.vtsc_offset;
             *gtsc_khz =  d->arch.tsc_khz;
-        }  else {
+        }
+        else
+        {
             uint64_t tsc = 0;
             rdtscll(tsc);
             *elapsed_nsec = scale_delta(tsc,&d->arch.vtsc_to_ns);
@@ -1719,15 +1730,20 @@ void tsc_get_info(struct domain *d, uint
         {
             *elapsed_nsec = get_s_time() - d->arch.vtsc_offset;
             *gtsc_khz =  cpu_khz;
-        } else {
+        }
+        else
+        {
             uint64_t tsc = 0;
             rdtscll(tsc);
-            *elapsed_nsec = scale_delta(tsc,&d->arch.vtsc_to_ns) -
-                            d->arch.vtsc_offset;
+            *elapsed_nsec = (scale_delta(tsc,&d->arch.vtsc_to_ns) -
+                             d->arch.vtsc_offset);
             *gtsc_khz = 0; /* ignored by tsc_set_info */
         }
         break;
     }
+
+    if ( (int64_t)*elapsed_nsec < 0 )
+        *elapsed_nsec = 0;
 }
 
 /*

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.