int __init check_nmi_watchdog (void) { irq_cpustat_t tmp[NR_CPUS]; int j, cpu; if (nmi_watchdog == NMI_LOCAL_APIC && !cpu_has_lapic()) return -1; printk(KERN_INFO "testing NMI watchdog ... "); memcpy(tmp, irq_stat, sizeof(tmp)); sti(); mdelay((10*1000)/nmi_hz); // wait 10 ticks for (j = 0; j < smp_num_cpus; j++) { cpu = cpu_logical_map(j); if (nmi_count(cpu) - tmp[cpu].__nmi_count <= 5) { printk("CPU#%d: NMI appears to be stuck!\n", cpu); return -1; } } printk("OK.\n"); /* now that we know it works we can reduce NMI frequency to something more reasonable; makes a difference in some configs */ if (nmi_watchdog == NMI_LOCAL_APIC) nmi_hz = 1; return 0; }
static int __init check_nmi_watchdog (void) { int counts[NR_CPUS]; int cpu; if (nmi_watchdog == NMI_NONE) return 0; if (nmi_watchdog == NMI_LOCAL_APIC && !cpu_has_lapic()) { nmi_watchdog = NMI_NONE; return -1; } printk(KERN_INFO "Testing NMI watchdog ... "); for (cpu = 0; cpu < NR_CPUS; cpu++) counts[cpu] = cpu_pda[cpu].__nmi_count; local_irq_enable(); mdelay((10*1000)/nmi_hz); // wait 10 ticks for (cpu = 0; cpu < NR_CPUS; cpu++) { #ifdef CONFIG_SMP /* Check cpu_callin_map here because that is set after the timer is started. */ if (!cpu_isset(cpu, cpu_callin_map)) continue; #endif if (cpu_pda[cpu].__nmi_count - counts[cpu] <= 5) { printk("CPU#%d: NMI appears to be stuck (%d)!\n", cpu, cpu_pda[cpu].__nmi_count); nmi_active = 0; lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG; return -1; } } printk("OK.\n"); /* now that we know it works we can reduce NMI frequency to something more reasonable; makes a difference in some configs */ if (nmi_watchdog == NMI_LOCAL_APIC) nmi_hz = 1; return 0; }