diff mbox

2.6.35-rc1 regression with pvclock and smp guests

Message ID 4CA75969.1080405@xutrox.com (mailing list archive)
State New, archived
Headers show

Commit Message

Arjan Koers Oct. 2, 2010, 4:10 p.m. UTC
None
diff mbox

Patch

diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c
index 239427c..5eab569 100644
--- a/arch/x86/kernel/pvclock.c
+++ b/arch/x86/kernel/pvclock.c
@@ -120,12 +120,15 @@  unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src)

 static atomic64_t last_value = ATOMIC64_INIT(0);

+int pvclock_backwards = 0;
+
 cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src)
 {
 	struct pvclock_shadow_time shadow;
 	unsigned version;
 	cycle_t ret, offset;
 	u64 last;
+	bool backwards;

 	do {
 		version = pvclock_get_time_values(&shadow, src);
@@ -153,13 +156,26 @@  cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src)
 	 * updating at the same time, and one of them could be slightly behind,
 	 * making the assumption that last_value always go forward fail to hold.
 	 */
+	backwards = false;
 	last = atomic64_read(&last_value);
 	do {
-		if (ret < last)
-			return last;
+		if (ret < last) {
+			if ( last - ret < 25000000 )
+				return last;
+			else
+				/* The clock will go backwards instead of being stuck at last value for a very long time
+				 * The return value of the previous call to pvclock_clocksource_read was most probably
+				 * very far into te future because the clock for that CPU hadn't been setup yet
+				 */
+				backwards = true;
+		}
 		last = atomic64_cmpxchg(&last_value, last, ret);
 	} while (unlikely(last != ret));

+	/* Increment outside of the while loop, because it always loops twice */
+	if (backwards)
+		pvclock_backwards++;
+
 	return ret;
 }

diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 0bf2ece..d6dcd45 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1,3 +1,5 @@ 
+#define DEBUG
+
 /*
  *	x86 SMP booting functions
  *
diff --git a/kernel/printk.c b/kernel/printk.c
index 444b770..9608bec 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -687,6 +687,8 @@  static inline void printk_delay(void)
 	}
 }

+extern int pvclock_backwards;
+
 asmlinkage int vprintk(const char *fmt, va_list args)
 {
 	int printed_len = 0;
@@ -778,9 +780,13 @@  asmlinkage int vprintk(const char *fmt, va_list args)
 				unsigned long long t;
 				unsigned long nanosec_rem;

+				int pvclock_backwards_prev = pvclock_backwards;
 				t = cpu_clock(printk_cpu);
 				nanosec_rem = do_div(t, 1000000000);
-				tlen = sprintf(tbuf, "[%5lu.%06lu] ",
+				tlen = sprintf(tbuf, "[%d;%d/%d:%5lu.%06lu] ",
+						printk_cpu,
+						pvclock_backwards_prev,
+						pvclock_backwards,
 						(unsigned long) t,
 						nanosec_rem / 1000);