From: Keir Fraser Date: Mon, 22 Feb 2010 10:03:18 +0000 (+0000) Subject: linux/x86: fix long timeout handling in stop_hz_timer() X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=5489f3aa473935b85849c06324d3e5b67fbc33b9;p=legacy%2Flinux-2.6.18-xen.git linux/x86: fix long timeout handling in stop_hz_timer() Other than for HYPERVISOR_set_timer_op, zero doesn't mean "no timeout" for VCPUOP_set_singleshot_timer (but should be retained rather than adjusted by NS_PER_TICK/2 for the former). Also properly cancel the singleshot timer is start_hz_timer(). Signed-off-by: Jan Beulich --- diff --git a/arch/i386/kernel/time-xen.c b/arch/i386/kernel/time-xen.c index 9d7e342e..90ac8ce4 100644 --- a/arch/i386/kernel/time-xen.c +++ b/arch/i386/kernel/time-xen.c @@ -1022,7 +1022,10 @@ static void stop_hz_timer(void) j = jiffies + 1; } - singleshot.timeout_abs_ns = jiffies_to_st(j) + NS_PER_TICK/2; + singleshot.timeout_abs_ns = jiffies_to_st(j); + if (!singleshot.timeout_abs_ns) + return; + singleshot.timeout_abs_ns += NS_PER_TICK / 2; singleshot.flags = 0; rc = HYPERVISOR_vcpu_op(VCPUOP_set_singleshot_timer, cpu, &singleshot); #if CONFIG_XEN_COMPAT <= 0x030004 @@ -1036,7 +1039,17 @@ static void stop_hz_timer(void) static void start_hz_timer(void) { - cpu_clear(smp_processor_id(), nohz_cpu_mask); + unsigned int cpu = smp_processor_id(); + int rc = HYPERVISOR_vcpu_op(VCPUOP_stop_singleshot_timer, cpu, NULL); + +#if CONFIG_XEN_COMPAT <= 0x030004 + if (rc) { + BUG_ON(rc != -ENOSYS); + rc = HYPERVISOR_set_timer_op(0); + } +#endif + BUG_ON(rc); + cpu_clear(cpu, nohz_cpu_mask); } void raw_safe_halt(void)