int __init check_nmi_watchdog (void) { int counts[NR_CPUS]; int cpu; if (!atomic_read(&nmi_watchdog_active)) return 0; printk(KERN_INFO "testing NMI watchdog ... "); #ifdef CONFIG_SMP if (nmi_watchdog == NMI_LOCAL_APIC) smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0); #endif for (cpu = 0; cpu < NR_CPUS; cpu++) counts[cpu] = cpu_pda[cpu].__nmi_count; local_irq_enable(); mdelay((20 * 1000) / nmi_hz); /* wait 20 ticks */ endflag = 1; for (cpu = 0; cpu < NR_CPUS; cpu++) { if (!cpu_online(cpu)) continue; if (!per_cpu(wd_enabled, cpu)) continue; 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); if (atomic_dec_and_test(&nmi_watchdog_active)) nmi_active = 0; per_cpu(wd_enabled, cpu) = 0; goto error; } } if (!atomic_read(&nmi_watchdog_active)) { atomic_set(&nmi_watchdog_active, -1); nmi_active = -1; goto error; } 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 = lapic_adjust_nmi_hz(1); return 0; error: if (nmi_watchdog == NMI_IO_APIC) { if (!timer_through_8259) disable_8259A_irq(0); printk(KERN_INFO "NMI watchdog: disabling NMI delivery on LINT0 for all CPUs\n"); on_each_cpu(__acpi_nmi_disable, NULL, 0, 1); } return -2; }
static int __init check_nmi_watchdog(void) { unsigned int *prev_nmi_count; int cpu; if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DISABLED)) return 0; if (!atomic_read(&nmi_active)) return 0; prev_nmi_count = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL); if (!prev_nmi_count) return -1; printk(KERN_INFO "Testing NMI watchdog ... "); if (nmi_watchdog == NMI_LOCAL_APIC) smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0); for_each_possible_cpu(cpu) prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count; local_irq_enable(); mdelay((20*1000)/nmi_hz); // wait 20 ticks for_each_possible_cpu(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 (!per_cpu(wd_enabled, cpu)) continue; if (nmi_count(cpu) - prev_nmi_count[cpu] <= 5) { printk(KERN_WARNING "WARNING: CPU#%d: NMI " "appears to be stuck (%d->%d)!\n", cpu, prev_nmi_count[cpu], nmi_count(cpu)); per_cpu(wd_enabled, cpu) = 0; atomic_dec(&nmi_active); } } endflag = 1; if (!atomic_read(&nmi_active)) { kfree(prev_nmi_count); atomic_set(&nmi_active, -1); 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 = lapic_adjust_nmi_hz(1); kfree(prev_nmi_count); return 0; }
int __init check_nmi_watchdog(void) { unsigned int *prev_nmi_count; int cpu; if (!nmi_watchdog_active() || !atomic_read(&nmi_active)) return 0; prev_nmi_count = kmalloc(nr_cpu_ids * sizeof(int), GFP_KERNEL); if (!prev_nmi_count) goto error; printk(KERN_INFO "Testing NMI watchdog ... "); #ifdef CONFIG_SMP if (nmi_watchdog == NMI_LOCAL_APIC) smp_call_function(nmi_cpu_busy, (void *)&endflag, 0); #endif for_each_possible_cpu(cpu) prev_nmi_count[cpu] = get_nmi_count(cpu); local_irq_enable(); mdelay((20 * 1000) / nmi_hz); /* wait 20 ticks */ for_each_online_cpu(cpu) { if (!per_cpu(wd_enabled, cpu)) continue; if (get_nmi_count(cpu) - prev_nmi_count[cpu] <= 5) report_broken_nmi(cpu, prev_nmi_count); } endflag = 1; if (!atomic_read(&nmi_active)) { kfree(prev_nmi_count); atomic_set(&nmi_active, -1); goto error; } 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 = lapic_adjust_nmi_hz(1); kfree(prev_nmi_count); return 0; error: if (nmi_watchdog == NMI_IO_APIC) { if (!timer_through_8259) legacy_pic->chip->mask(0); on_each_cpu(__acpi_nmi_disable, NULL, 1); } #ifdef CONFIG_X86_32 timer_ack = 0; #endif return -1; }
int __init check_nmi_watchdog (void) { int *counts; int cpu; if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DISABLED)) return 0; if (!atomic_read(&nmi_active)) return 0; counts = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL); if (!counts) return -1; printk(KERN_INFO "testing NMI watchdog ... "); #ifdef CONFIG_SMP if (nmi_watchdog == NMI_LOCAL_APIC) smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0); #endif for (cpu = 0; cpu < NR_CPUS; cpu++) counts[cpu] = cpu_pda(cpu)->__nmi_count; local_irq_enable(); mdelay((20*1000)/nmi_hz); // wait 20 ticks for_each_online_cpu(cpu) { if (!per_cpu(wd_enabled, cpu)) continue; if (cpu_pda(cpu)->__nmi_count - counts[cpu] <= 5) { printk(KERN_WARNING "WARNING: CPU#%d: NMI " "appears to be stuck (%d->%d)!\n", cpu, counts[cpu], cpu_pda(cpu)->__nmi_count); per_cpu(wd_enabled, cpu) = 0; atomic_dec(&nmi_active); } } if (!atomic_read(&nmi_active)) { kfree(counts); atomic_set(&nmi_active, -1); endflag = 1; return -1; } endflag = 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 = lapic_adjust_nmi_hz(1); kfree(counts); return 0; }
int __init check_nmi_watchdog (void) { unsigned int prev_nmi_count[NR_CPUS]; int cpu; if (!atomic_read(&nmi_watchdog_active)) return 0; printk(KERN_INFO "testing NMI watchdog ... "); for (cpu = 0; cpu < NR_CPUS; cpu++) prev_nmi_count[cpu] = irq_stat[cpu].__nmi_count; local_irq_enable(); mdelay((10*1000)/nmi_hz); // wait 10 ticks /* FIXME: Only boot CPU is online at this stage. Check CPUs as they come up. */ for (cpu = 0; cpu < NR_CPUS; cpu++) { if (!cpu_online(cpu)) continue; if (!per_cpu(wd_enabled, cpu)) continue; if (nmi_count(cpu) - prev_nmi_count[cpu] <= 5) { printk("CPU#%d: NMI appears to be stuck!\n", cpu); if (atomic_dec_and_test(&nmi_watchdog_active)) nmi_active = 0; per_cpu(wd_enabled, cpu) = 0; return -1; } } if (!atomic_read(&nmi_watchdog_active)) { atomic_set(&nmi_watchdog_active, -1); nmi_active = -1; 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 = lapic_adjust_nmi_hz(1); return 0; }