arch/powerpc/kernel/watchdog.c
Source file repositories/reference/linux-study-clean/arch/powerpc/kernel/watchdog.c
File Facts
- System
- Linux kernel
- Corpus path
arch/powerpc/kernel/watchdog.c- Extension
.c- Size
- 16753 bytes
- Lines
- 596
- Domain
- Architecture Layer
- Bucket
- arch/powerpc
- 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.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/param.hlinux/init.hlinux/percpu.hlinux/cpu.hlinux/nmi.hlinux/module.hlinux/export.hlinux/kprobes.hlinux/hardirq.hlinux/reboot.hlinux/slab.hlinux/kdebug.hlinux/sched/debug.hlinux/delay.hlinux/processor.hlinux/smp.hlinux/sys_info.hasm/interrupt.hasm/paca.hasm/nmi.h
Detected Declarations
function againfunction wd_end_reportingfunction wd_smp_lockfunction wd_smp_unlockfunction wd_lockup_ipifunction set_cpu_stuckfunction watchdog_smp_panicfunction for_each_cpufunction wd_smp_clear_cpu_pendingfunction watchdog_timer_interruptfunction watchdog_timer_fnfunction arch_touch_nmi_watchdogfunction start_watchdogfunction start_watchdog_on_cpufunction stop_watchdogfunction stop_watchdog_on_cpufunction watchdog_calc_timeoutsfunction watchdog_hardlockup_stopfunction watchdog_hardlockup_startfunction watchdog_hardlockup_probefunction watchdog_hardlockup_set_timeout_pctexport arch_touch_nmi_watchdog
Annotated Snippet
for_each_cpu(c, &wd_smp_cpus_ipi) {
smp_send_nmi_ipi(c, wd_lockup_ipi, 1000000);
__cpumask_clear_cpu(c, &wd_smp_cpus_ipi);
}
}
sys_info(hardlockup_si_mask & ~SYS_INFO_ALL_BT);
if (hardlockup_panic)
nmi_panic(NULL, "Hard LOCKUP");
wd_end_reporting();
return;
out:
wd_smp_unlock(&flags);
}
static void wd_smp_clear_cpu_pending(int cpu)
{
if (!cpumask_test_cpu(cpu, &wd_smp_cpus_pending)) {
if (unlikely(cpumask_test_cpu(cpu, &wd_smp_cpus_stuck))) {
struct pt_regs *regs = get_irq_regs();
unsigned long flags;
pr_emerg("CPU %d became unstuck TB:%lld\n",
cpu, get_tb());
print_irqtrace_events(current);
if (regs)
show_regs(regs);
else
dump_stack();
wd_smp_lock(&flags);
cpumask_clear_cpu(cpu, &wd_smp_cpus_stuck);
wd_smp_unlock(&flags);
} else {
/*
* The last CPU to clear pending should have reset the
* watchdog so we generally should not find it empty
* here if our CPU was clear. However it could happen
* due to a rare race with another CPU taking the
* last CPU out of the mask concurrently.
*
* We can't add a warning for it. But just in case
* there is a problem with the watchdog that is causing
* the mask to not be reset, try to kick it along here.
*/
if (unlikely(cpumask_empty(&wd_smp_cpus_pending)))
goto none_pending;
}
return;
}
/*
* All other updates to wd_smp_cpus_pending are performed under
* wd_smp_lock. All of them are atomic except the case where the
* mask becomes empty and is reset. This will not happen here because
* cpu was tested to be in the bitmap (above), and a CPU only clears
* its own bit. _Except_ in the case where another CPU has detected a
* hard lockup on our CPU and takes us out of the pending mask. So in
* normal operation there will be no race here, no problem.
*
* In the lockup case, this atomic clear-bit vs a store that refills
* other bits in the accessed word wll not be a problem. The bit clear
* is atomic so it will not cause the store to get lost, and the store
* will never set this bit so it will not overwrite the bit clear. The
* only way for a stuck CPU to return to the pending bitmap is to
* become unstuck itself.
*/
cpumask_clear_cpu(cpu, &wd_smp_cpus_pending);
/*
* Order the store to clear pending with the load(s) to check all
* words in the pending mask to check they are all empty. This orders
* with the same barrier on another CPU. This prevents two CPUs
* clearing the last 2 pending bits, but neither seeing the other's
* store when checking if the mask is empty, and missing an empty
* mask, which ends with a false positive.
*/
smp_mb();
if (cpumask_empty(&wd_smp_cpus_pending)) {
unsigned long flags;
none_pending:
/*
* Double check under lock because more than one CPU could see
* a clear mask with the lockless check after clearing their
* pending bits.
*/
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/param.h`, `linux/init.h`, `linux/percpu.h`, `linux/cpu.h`, `linux/nmi.h`, `linux/module.h`, `linux/export.h`.
- Detected declarations: `function again`, `function wd_end_reporting`, `function wd_smp_lock`, `function wd_smp_unlock`, `function wd_lockup_ipi`, `function set_cpu_stuck`, `function watchdog_smp_panic`, `function for_each_cpu`, `function wd_smp_clear_cpu_pending`, `function watchdog_timer_interrupt`.
- Atlas domain: Architecture Layer / arch/powerpc.
- Implementation status: integration implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.