Example #1
0
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;
}
Example #2
0
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;
}
Example #3
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;
}
Example #4
0
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;
}
Example #5
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;
}