]> xenbits.xensource.com Git - people/royger/linux-2.6.18-xen.git/commitdiff
linux/x86: fix long timeout handling in stop_hz_timer()
authorKeir Fraser <keir.fraser@citrix.com>
Mon, 22 Feb 2010 10:03:18 +0000 (10:03 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Mon, 22 Feb 2010 10:03:18 +0000 (10:03 +0000)
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 <jbeulich@novell.com>
arch/i386/kernel/time-xen.c

index 9d7e342e254e09a9add402d6638f9ba21d147fec..90ac8ce4a8cc39db531bb7c5e9ccc7956303bc09 100644 (file)
@@ -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)