diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/kernel/vmi.c | 23 | ||||
-rw-r--r-- | arch/i386/kernel/vmitime.c | 30 |
2 files changed, 24 insertions, 29 deletions
diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index bb5a7abf949c..8417f741fac8 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c | |||
@@ -54,6 +54,7 @@ static int disable_pse; | |||
54 | static int disable_sep; | 54 | static int disable_sep; |
55 | static int disable_tsc; | 55 | static int disable_tsc; |
56 | static int disable_mtrr; | 56 | static int disable_mtrr; |
57 | static int disable_noidle; | ||
57 | 58 | ||
58 | /* Cached VMI operations */ | 59 | /* Cached VMI operations */ |
59 | struct { | 60 | struct { |
@@ -255,7 +256,6 @@ static void vmi_nop(void) | |||
255 | } | 256 | } |
256 | 257 | ||
257 | /* For NO_IDLE_HZ, we stop the clock when halting the kernel */ | 258 | /* For NO_IDLE_HZ, we stop the clock when halting the kernel */ |
258 | #ifdef CONFIG_NO_IDLE_HZ | ||
259 | static fastcall void vmi_safe_halt(void) | 259 | static fastcall void vmi_safe_halt(void) |
260 | { | 260 | { |
261 | int idle = vmi_stop_hz_timer(); | 261 | int idle = vmi_stop_hz_timer(); |
@@ -266,7 +266,6 @@ static fastcall void vmi_safe_halt(void) | |||
266 | local_irq_enable(); | 266 | local_irq_enable(); |
267 | } | 267 | } |
268 | } | 268 | } |
269 | #endif | ||
270 | 269 | ||
271 | #ifdef CONFIG_DEBUG_PAGE_TYPE | 270 | #ifdef CONFIG_DEBUG_PAGE_TYPE |
272 | 271 | ||
@@ -742,12 +741,7 @@ static inline int __init activate_vmi(void) | |||
742 | (char *)paravirt_ops.save_fl); | 741 | (char *)paravirt_ops.save_fl); |
743 | patch_offset(&irq_save_disable_callout[IRQ_PATCH_DISABLE], | 742 | patch_offset(&irq_save_disable_callout[IRQ_PATCH_DISABLE], |
744 | (char *)paravirt_ops.irq_disable); | 743 | (char *)paravirt_ops.irq_disable); |
745 | #ifndef CONFIG_NO_IDLE_HZ | 744 | |
746 | para_fill(safe_halt, Halt); | ||
747 | #else | ||
748 | vmi_ops.halt = vmi_get_function(VMI_CALL_Halt); | ||
749 | paravirt_ops.safe_halt = vmi_safe_halt; | ||
750 | #endif | ||
751 | para_fill(wbinvd, WBINVD); | 745 | para_fill(wbinvd, WBINVD); |
752 | /* paravirt_ops.read_msr = vmi_rdmsr */ | 746 | /* paravirt_ops.read_msr = vmi_rdmsr */ |
753 | /* paravirt_ops.write_msr = vmi_wrmsr */ | 747 | /* paravirt_ops.write_msr = vmi_wrmsr */ |
@@ -881,6 +875,12 @@ static inline int __init activate_vmi(void) | |||
881 | #endif | 875 | #endif |
882 | custom_sched_clock = vmi_sched_clock; | 876 | custom_sched_clock = vmi_sched_clock; |
883 | } | 877 | } |
878 | if (!disable_noidle) | ||
879 | para_fill(safe_halt, Halt); | ||
880 | else { | ||
881 | vmi_ops.halt = vmi_get_function(VMI_CALL_Halt); | ||
882 | paravirt_ops.safe_halt = vmi_safe_halt; | ||
883 | } | ||
884 | 884 | ||
885 | /* | 885 | /* |
886 | * Alternative instruction rewriting doesn't happen soon enough | 886 | * Alternative instruction rewriting doesn't happen soon enough |
@@ -914,9 +914,11 @@ void __init vmi_init(void) | |||
914 | 914 | ||
915 | local_irq_save(flags); | 915 | local_irq_save(flags); |
916 | activate_vmi(); | 916 | activate_vmi(); |
917 | #ifdef CONFIG_SMP | 917 | |
918 | #ifdef CONFIG_X86_IO_APIC | ||
918 | no_timer_check = 1; | 919 | no_timer_check = 1; |
919 | #endif | 920 | #endif |
921 | |||
920 | local_irq_restore(flags & X86_EFLAGS_IF); | 922 | local_irq_restore(flags & X86_EFLAGS_IF); |
921 | } | 923 | } |
922 | 924 | ||
@@ -942,7 +944,8 @@ static int __init parse_vmi(char *arg) | |||
942 | } else if (!strcmp(arg, "disable_mtrr")) { | 944 | } else if (!strcmp(arg, "disable_mtrr")) { |
943 | clear_bit(X86_FEATURE_MTRR, boot_cpu_data.x86_capability); | 945 | clear_bit(X86_FEATURE_MTRR, boot_cpu_data.x86_capability); |
944 | disable_mtrr = 1; | 946 | disable_mtrr = 1; |
945 | } | 947 | } else if (!strcmp(arg, "disable_noidle")) |
948 | disable_noidle = 1; | ||
946 | return 0; | 949 | return 0; |
947 | } | 950 | } |
948 | 951 | ||
diff --git a/arch/i386/kernel/vmitime.c b/arch/i386/kernel/vmitime.c index 76d2adcae5a3..694aa85d22c2 100644 --- a/arch/i386/kernel/vmitime.c +++ b/arch/i386/kernel/vmitime.c | |||
@@ -276,16 +276,13 @@ static void vmi_account_real_cycles(unsigned long long cur_real_cycles) | |||
276 | 276 | ||
277 | cycles_not_accounted = cur_real_cycles - real_cycles_accounted_system; | 277 | cycles_not_accounted = cur_real_cycles - real_cycles_accounted_system; |
278 | while (cycles_not_accounted >= cycles_per_jiffy) { | 278 | while (cycles_not_accounted >= cycles_per_jiffy) { |
279 | /* systems wide jiffies and wallclock. */ | 279 | /* systems wide jiffies. */ |
280 | do_timer(1); | 280 | do_timer(1); |
281 | 281 | ||
282 | cycles_not_accounted -= cycles_per_jiffy; | 282 | cycles_not_accounted -= cycles_per_jiffy; |
283 | real_cycles_accounted_system += cycles_per_jiffy; | 283 | real_cycles_accounted_system += cycles_per_jiffy; |
284 | } | 284 | } |
285 | 285 | ||
286 | if (vmi_timer_ops.wallclock_updated()) | ||
287 | update_xtime_from_wallclock(); | ||
288 | |||
289 | write_sequnlock(&xtime_lock); | 286 | write_sequnlock(&xtime_lock); |
290 | } | 287 | } |
291 | 288 | ||
@@ -380,7 +377,6 @@ int vmi_stop_hz_timer(void) | |||
380 | unsigned long seq, next; | 377 | unsigned long seq, next; |
381 | unsigned long long real_cycles_expiry; | 378 | unsigned long long real_cycles_expiry; |
382 | int cpu = smp_processor_id(); | 379 | int cpu = smp_processor_id(); |
383 | int idle; | ||
384 | 380 | ||
385 | BUG_ON(!irqs_disabled()); | 381 | BUG_ON(!irqs_disabled()); |
386 | if (sysctl_hz_timer != 0) | 382 | if (sysctl_hz_timer != 0) |
@@ -388,13 +384,13 @@ int vmi_stop_hz_timer(void) | |||
388 | 384 | ||
389 | cpu_set(cpu, nohz_cpu_mask); | 385 | cpu_set(cpu, nohz_cpu_mask); |
390 | smp_mb(); | 386 | smp_mb(); |
387 | |||
391 | if (rcu_needs_cpu(cpu) || local_softirq_pending() || | 388 | if (rcu_needs_cpu(cpu) || local_softirq_pending() || |
392 | (next = next_timer_interrupt(), time_before_eq(next, jiffies))) { | 389 | (next = next_timer_interrupt(), |
390 | time_before_eq(next, jiffies + HZ/CONFIG_VMI_ALARM_HZ))) { | ||
393 | cpu_clear(cpu, nohz_cpu_mask); | 391 | cpu_clear(cpu, nohz_cpu_mask); |
394 | next = jiffies; | 392 | return 0; |
395 | idle = 0; | 393 | } |
396 | } else | ||
397 | idle = 1; | ||
398 | 394 | ||
399 | /* Convert jiffies to the real cycle counter. */ | 395 | /* Convert jiffies to the real cycle counter. */ |
400 | do { | 396 | do { |
@@ -404,17 +400,13 @@ int vmi_stop_hz_timer(void) | |||
404 | } while (read_seqretry(&xtime_lock, seq)); | 400 | } while (read_seqretry(&xtime_lock, seq)); |
405 | 401 | ||
406 | /* This cpu is going idle. Disable the periodic alarm. */ | 402 | /* This cpu is going idle. Disable the periodic alarm. */ |
407 | if (idle) { | 403 | vmi_timer_ops.cancel_alarm(VMI_CYCLES_AVAILABLE); |
408 | vmi_timer_ops.cancel_alarm(VMI_CYCLES_AVAILABLE); | 404 | per_cpu(idle_start_jiffies, cpu) = jiffies; |
409 | per_cpu(idle_start_jiffies, cpu) = jiffies; | ||
410 | } | ||
411 | |||
412 | /* Set the real time alarm to expire at the next event. */ | 405 | /* Set the real time alarm to expire at the next event. */ |
413 | vmi_timer_ops.set_alarm( | 406 | vmi_timer_ops.set_alarm( |
414 | VMI_ALARM_WIRING | VMI_ALARM_IS_ONESHOT | VMI_CYCLES_REAL, | 407 | VMI_ALARM_WIRING | VMI_ALARM_IS_ONESHOT | VMI_CYCLES_REAL, |
415 | real_cycles_expiry, 0); | 408 | real_cycles_expiry, 0); |
416 | 409 | return 1; | |
417 | return idle; | ||
418 | } | 410 | } |
419 | 411 | ||
420 | static void vmi_reenable_hz_timer(int cpu) | 412 | static void vmi_reenable_hz_timer(int cpu) |