From: Chris Lalancette <clalance@redhat.com> Date: Fri, 20 Mar 2009 10:24:09 +0100 Subject: [x86] vmware: disable softlock processing on tsc systems Message-id: 49C360B9.8080003@redhat.com O-Subject: [RHEL5.4 PATCH 13/14]: x86: Disable softlock processing with tsc based timekeeping algorithm Bugzilla: 463573 RH-Acked-by: Rik van Riel <riel@redhat.com> RH-Acked-by: Justin M. Forbes <jforbes@redhat.com> The softlockup warning indicates that some amount of time has gone by without having the kernel schedule the softlockup thread (i.e. it's detecting cases where the kernel is not able to reschedule). Normally, this indicates a kernel bug. When running on a hypervisor, though, it is possible to hit this scenario even when there is no real bug. It can happen when the hypervisor is under high load, and does not schedule the VM often enough. With the TSC timekeeping algorithm, we can have a situation where the time in the VM stays correct regardless of how frequently the VM is able to run. Thus, the kernel will now notice that time had passed even though it had not had a chance to run (and therefore not reschedule its processes) and so the softlockup warning is more likely to warn in this case, which is clearly a false positive from kernels perspective. There is no clear way for the kernel to detect all these corner cases so that it could notify the softlockup code when the VM was descheduled by the hypervisor. So for now, we disable the softlockup watchdog when using the new TSC based algorithm, under VMware. Note that this is not needed upstream; there it is mostly handled by schedclock. Fixes BZ 463573 diff --git a/arch/i386/kernel/cpu/vmware.c b/arch/i386/kernel/cpu/vmware.c index 2ca3a3b..6a039f2 100644 --- a/arch/i386/kernel/cpu/vmware.c +++ b/arch/i386/kernel/cpu/vmware.c @@ -26,6 +26,8 @@ #include <asm/div64.h> #include <asm/vmware.h> +extern int __initdata nosoftlockup; + #define CPUID_VMWARE_INFO_LEAF 0x40000000 #define VMWARE_HYPERVISOR_MAGIC 0x564D5868 #define VMWARE_HYPERVISOR_PORT 0x5658 @@ -113,9 +115,17 @@ unsigned long vmware_get_tsc_khz(void) #ifdef CONFIG_X86_64 { extern int timekeeping_use_tsc; + if (vm_tsc_khz && timekeeping_use_tsc >= 0) { - if (vmware_enable_lazy_timer_emulation()) + if (vmware_enable_lazy_timer_emulation()) { timekeeping_use_tsc = 1; + /* + * Disable softlockups if using TSC based + * timekeeping, as this may have false + * positives when running under hypervisors. + */ + nosoftlockup = 1; + } else { printk(KERN_WARNING "time.c: failed to enable lazy timer " diff --git a/init/main.c b/init/main.c index 2c8e461..06349fe 100644 --- a/init/main.c +++ b/init/main.c @@ -720,7 +720,7 @@ static void __init do_basic_setup(void) do_initcalls(); } -static int __initdata nosoftlockup; +int __initdata nosoftlockup; static int __init nosoftlockup_setup(char *str) {