]> Pileus Git - ~andy/linux/blobdiff - arch/x86/kernel/nmi_32.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[~andy/linux] / arch / x86 / kernel / nmi_32.c
index c7227e2180f850bde4a04de8a0e4417045bd6be2..f5cc47c60b1372729568c5c0f7fdd5bad369b70e 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  linux/arch/i386/nmi.c
- *
  *  NMI watchdog support on APIC systems
  *
  *  Started by Ingo Molnar <mingo@redhat.com>
@@ -27,6 +25,7 @@
 
 #include <asm/smp.h>
 #include <asm/nmi.h>
+#include <asm/timer.h>
 
 #include "mach_traps.h"
 
@@ -53,13 +52,13 @@ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu);
 
 static int endflag __initdata = 0;
 
-#ifdef CONFIG_SMP
 /* The performance counters used by NMI_LOCAL_APIC don't trigger when
  * the CPU is idle. To make sure the NMI watchdog really ticks on all
  * CPUs during the test make them busy.
  */
 static __init void nmi_cpu_busy(void *data)
 {
+#ifdef CONFIG_SMP
        local_irq_enable_in_hardirq();
        /* Intentionally don't use cpu_relax here. This is
           to make sure that the performance counter really ticks,
@@ -69,8 +68,8 @@ static __init void nmi_cpu_busy(void *data)
           care if they get somewhat less cycles. */
        while (endflag == 0)
                mb();
-}
 #endif
+}
 
 static int __init check_nmi_watchdog(void)
 {
@@ -85,7 +84,7 @@ static int __init check_nmi_watchdog(void)
 
        prev_nmi_count = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL);
        if (!prev_nmi_count)
-               return -1;
+               goto error;
 
        printk(KERN_INFO "Testing NMI watchdog ... ");
 
@@ -119,7 +118,7 @@ static int __init check_nmi_watchdog(void)
        if (!atomic_read(&nmi_active)) {
                kfree(prev_nmi_count);
                atomic_set(&nmi_active, -1);
-               return -1;
+               goto error;
        }
        printk("OK.\n");
 
@@ -130,6 +129,10 @@ static int __init check_nmi_watchdog(void)
 
        kfree(prev_nmi_count);
        return 0;
+error:
+       timer_ack = !cpu_has_tsc;
+
+       return -1;
 }
 /* This needs to happen later in boot so counters are working */
 late_initcall(check_nmi_watchdog);
@@ -353,7 +356,8 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
         * Take the local apic timer and PIT/HPET into account. We don't
         * know which one is active, when we have highres/dyntick on
         */
-       sum = per_cpu(irq_stat, cpu).apic_timer_irqs + kstat_cpu(cpu).irqs[0];
+       sum = per_cpu(irq_stat, cpu).apic_timer_irqs +
+               per_cpu(irq_stat, cpu).irq0_irqs;
 
        /* if the none of the timers isn't firing, this cpu isn't doing much */
        if (!touched && last_irq_sums[cpu] == sum) {