]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/xen/time.c
Merge branch 'linus' into x86/xen
[linux-2.6-omap-h63xx.git] / arch / x86 / xen / time.c
index dfd6db69ead5072dd5a7430ad4750285d44d7031..0da249dbdc49b992c966142c354ce1877628c605 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/kernel_stat.h>
+#include <linux/math64.h>
 
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypercall.h>
@@ -105,6 +106,12 @@ static void get_runstate_snapshot(struct vcpu_runstate_info *res)
        } while (get64(&state->state_entry_time) != state_time);
 }
 
+/* return true when a vcpu could run but has no real cpu to run on */
+bool xen_vcpu_stolen(int vcpu)
+{
+       return per_cpu(runstate, vcpu).state == RUNSTATE_runnable;
+}
+
 static void setup_runstate_info(int cpu)
 {
        struct vcpu_register_runstate_memory_area area;
@@ -144,11 +151,7 @@ static void do_stolen_accounting(void)
        if (stolen < 0)
                stolen = 0;
 
-       ticks = 0;
-       while (stolen >= NS_PER_TICK) {
-               ticks++;
-               stolen -= NS_PER_TICK;
-       }
+       ticks = iter_div_u64_rem(stolen, NS_PER_TICK, &stolen);
        __get_cpu_var(residual_stolen) = stolen;
        account_steal_time(NULL, ticks);
 
@@ -160,11 +163,7 @@ static void do_stolen_accounting(void)
        if (blocked < 0)
                blocked = 0;
 
-       ticks = 0;
-       while (blocked >= NS_PER_TICK) {
-               ticks++;
-               blocked -= NS_PER_TICK;
-       }
+       ticks = iter_div_u64_rem(blocked, NS_PER_TICK, &blocked);
        __get_cpu_var(residual_blocked) = blocked;
        account_steal_time(idle_task(smp_processor_id()), ticks);
 }
@@ -211,17 +210,17 @@ unsigned long long xen_sched_clock(void)
 /* Get the CPU speed from Xen */
 unsigned long xen_cpu_khz(void)
 {
-       u64 cpu_khz = 1000000ULL << 32;
+       u64 xen_khz = 1000000ULL << 32;
        const struct vcpu_time_info *info =
                &HYPERVISOR_shared_info->vcpu_info[0].time;
 
-       do_div(cpu_khz, info->tsc_to_system_mul);
+       do_div(xen_khz, info->tsc_to_system_mul);
        if (info->tsc_shift < 0)
-               cpu_khz <<= -info->tsc_shift;
+               xen_khz <<= -info->tsc_shift;
        else
-               cpu_khz >>= info->tsc_shift;
+               xen_khz >>= info->tsc_shift;
 
-       return cpu_khz;
+       return xen_khz;
 }
 
 /*
@@ -566,6 +565,19 @@ void xen_setup_cpu_clockevents(void)
        clockevents_register_device(&__get_cpu_var(xen_clock_events));
 }
 
+void xen_timer_resume(void)
+{
+       int cpu;
+
+       if (xen_clockevent != &xen_vcpuop_clockevent)
+               return;
+
+       for_each_online_cpu(cpu) {
+               if (HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer, cpu, NULL))
+                       BUG();
+       }
+}
+
 __init void xen_time_init(void)
 {
        int cpu = smp_processor_id();
@@ -586,7 +598,7 @@ __init void xen_time_init(void)
        set_normalized_timespec(&wall_to_monotonic,
                                -xtime.tv_sec, -xtime.tv_nsec);
 
-       tsc_disable = 0;
+       setup_force_cpu_cap(X86_FEATURE_TSC);
 
        xen_setup_timer(cpu);
        xen_setup_cpu_clockevents();