arch/sparc/kernel/nmi.c

Source file repositories/reference/linux-study-clean/arch/sparc/kernel/nmi.c

File Facts

System
Linux kernel
Corpus path
arch/sparc/kernel/nmi.c
Extension
.c
Size
7245 bytes
Lines
318
Domain
Architecture Layer
Bucket
arch/sparc
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

for_each_present_cpu(cpu) {
			if (per_cpu(nmi_touch, cpu) != 1)
				per_cpu(nmi_touch, cpu) = 1;
		}
	}
}
EXPORT_SYMBOL(arch_touch_nmi_watchdog);

int __init watchdog_hardlockup_probe(void)
{
	return 0;
}

static void die_nmi(const char *str, struct pt_regs *regs, int do_panic)
{
	int this_cpu = smp_processor_id();

	if (notify_die(DIE_NMIWATCHDOG, str, regs, 0,
		       pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
		return;

	if (do_panic || panic_on_oops)
		panic("Watchdog detected hard LOCKUP on cpu %d", this_cpu);
	else
		WARN(1, "Watchdog detected hard LOCKUP on cpu %d", this_cpu);
}

notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
{
	unsigned int sum, touched = 0;
	void *orig_sp;

	clear_softint(1 << irq);

	local_cpu_data().__nmi_count++;

	nmi_enter();

	orig_sp = set_hardirq_stack();

	if (notify_die(DIE_NMI, "nmi", regs, 0,
		       pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
		touched = 1;
	else
		pcr_ops->write_pcr(0, pcr_ops->pcr_nmi_disable);

	sum = local_cpu_data().irq0_irqs;
	if (__this_cpu_read(nmi_touch)) {
		__this_cpu_write(nmi_touch, 0);
		touched = 1;
	}
	if (!touched && __this_cpu_read(last_irq_sum) == sum) {
		__this_cpu_inc(alert_counter);
		if (__this_cpu_read(alert_counter) == 30 * nmi_hz)
			die_nmi("BUG: NMI Watchdog detected LOCKUP",
				regs, panic_on_timeout);
	} else {
		__this_cpu_write(last_irq_sum, sum);
		__this_cpu_write(alert_counter, 0);
	}
	if (__this_cpu_read(wd_enabled)) {
		pcr_ops->write_pic(0, pcr_ops->nmi_picl_value(nmi_hz));
		pcr_ops->write_pcr(0, pcr_ops->pcr_nmi_enable);
	}

	restore_hardirq_stack(orig_sp);

	nmi_exit();
}

static inline unsigned int get_nmi_count(int cpu)
{
	return cpu_data(cpu).__nmi_count;
}

static __init void nmi_cpu_busy(void *data)
{
	while (endflag == 0)
		mb();
}

static void report_broken_nmi(int cpu, int *prev_nmi_count)
{
	printk(KERN_CONT "\n");

	printk(KERN_WARNING
		"WARNING: CPU#%d: NMI appears to be stuck (%d->%d)!\n",
			cpu, prev_nmi_count[cpu], get_nmi_count(cpu));

	printk(KERN_WARNING

Annotation

Implementation Notes