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

[Xen-changelog] [xen-4.0-testing] x86: Detect and handle unexpected platform-timer counter wrap.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1281541443 -3600
# Node ID 8e8dd38374e9758412b079bf2edda1909ef157dd
# Parent  954754745f65f0a76519924184062958d62f6744
x86: Detect and handle unexpected platform-timer counter wrap.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
xen-unstable changeset:   21346:7d4deb86b966
xen-unstable date:        Tue May 11 11:21:27 2010 +0100
---
 xen/arch/x86/time.c |   36 +++++++++++++++++++++++++++++-------
 1 files changed, 29 insertions(+), 7 deletions(-)

diff -r 954754745f65 -r 8e8dd38374e9 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c       Wed Aug 11 16:43:44 2010 +0100
+++ b/xen/arch/x86/time.c       Wed Aug 11 16:44:03 2010 +0100
@@ -571,24 +571,46 @@ static u64 plt_stamp;            /* hard
 static u64 plt_stamp;            /* hardware-width platform counter stamp   */
 static struct timer plt_overflow_timer;
 
+static s_time_t __read_platform_stime(u64 platform_time)
+{
+    u64 diff = platform_time - platform_timer_stamp;
+    ASSERT(spin_is_locked(&platform_timer_lock));
+    return (stime_platform_stamp + scale_delta(diff, &plt_scale));
+}
+
 static void plt_overflow(void *unused)
 {
+    int i;
     u64 count;
+    s_time_t now, plt_now, plt_wrap;
 
     spin_lock_irq(&platform_timer_lock);
+
     count = plt_src.read_counter();
     plt_stamp64 += (count - plt_stamp) & plt_mask;
     plt_stamp = count;
+
+    now = NOW();
+    plt_wrap = __read_platform_stime(plt_stamp64);
+    for ( i = 0; i < 10; i++ )
+    {
+        plt_now = plt_wrap;
+        plt_wrap = __read_platform_stime(plt_stamp64 + plt_mask + 1);
+        if ( ABS(plt_wrap - now) > ABS(plt_now - now) )
+            break;
+        plt_stamp64 += plt_mask + 1;
+    }
+    if ( i != 0 )
+    {
+        static bool_t warned_once;
+        if ( !test_and_set_bool(warned_once) )
+            printk("Platform timer appears to have unexpectedly wrapped "
+                   "%u%s times.\n", i, (i == 10) ? " or more" : "");
+    }
+
     spin_unlock_irq(&platform_timer_lock);
 
     set_timer(&plt_overflow_timer, NOW() + plt_overflow_period);
-}
-
-static s_time_t __read_platform_stime(u64 platform_time)
-{
-    u64 diff = platform_time - platform_timer_stamp;
-    ASSERT(spin_is_locked(&platform_timer_lock));
-    return (stime_platform_stamp + scale_delta(diff, &plt_scale));
 }
 
 static s_time_t read_platform_stime(void)

_______________________________________________
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®.