From bdeaacf558cedfaff40c565f697c2da75122a1cd Mon Sep 17 00:00:00 2001 From: Frank Pan Date: Tue, 22 Mar 2011 02:04:55 +0800 Subject: [PATCH] [Bugfix][pv-ops] Guest get stucked after migration In recent pv-ops kernel, pvclock is not guaranteed as monotone. After the migration, pvclock can produce smaller cycle count. [The test is performed on next-2.6.32 tree] The issue occured when uptime(sender) > uptime(target), and with CONFIG_GENERIC_TIME. The guest get stucked after the migration, doing a huge loop inside update_wall_time, until the overflow of 64-bit unsigned offset. The following patch fixed this issue by introducing a global sign. Xen pvclock will update the cycle_last with the newest cycle count on the first read after migration. Signed-off-by: Frank Pan --- linux-2.6-xen/arch/x86/xen/time.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-) diff --git a/linux-2.6-xen/arch/x86/xen/time.c b/linux-2.6-xen/arch/x86/xen/time.c index ab35140..ac6fe2a 100644 --- a/linux-2.6-xen/arch/x86/xen/time.c +++ b/linux-2.6-xen/arch/x86/xen/time.c @@ -41,6 +41,9 @@ static DEFINE_PER_CPU(struct vcpu_runstate_info, runstate_snapshot); static DEFINE_PER_CPU(u64, residual_stolen); static DEFINE_PER_CPU(u64, residual_blocked); +/* xen_clocksource_get_cycles should update cycle_last after resume */ +static int just_resume = 0; + /* return an consistent snapshot of 64-bit time/counter value */ static u64 get64(const u64 *p) { @@ -177,7 +180,13 @@ cycle_t xen_clocksource_read(void) static cycle_t xen_clocksource_get_cycles(struct clocksource *cs) { - return xen_clocksource_read(); + cycle_t c = xen_clocksource_read(); + + if (unlikely(just_resume)) { + cs->cycle_last = c++; + just_resume = 0; + } + return c; } static void xen_read_wallclock(struct timespec *ts) @@ -441,6 +450,7 @@ void xen_timer_resume(void) { int cpu; + just_resume = 1; pvclock_resume(); if (xen_clockevent != &xen_vcpuop_clockevent) -- 1.7.0.4