kernel/watchdog.c
Source file repositories/reference/linux-study-clean/kernel/watchdog.c
File Facts
- System
- Linux kernel
- Corpus path
kernel/watchdog.c- Extension
.c- Size
- 38848 bytes
- Lines
- 1401
- Domain
- Core OS
- Bucket
- Scheduler, Processes, Timers, Sync, And Syscalls
- Inferred role
- Core OS: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/cpu.hlinux/init.hlinux/irq.hlinux/irqdesc.hlinux/kernel_stat.hlinux/kvm_para.hlinux/math64.hlinux/mm.hlinux/module.hlinux/nmi.hlinux/stop_machine.hlinux/sysctl.hlinux/tick.hlinux/sys_info.hlinux/sched/clock.hlinux/sched/debug.hlinux/sched/isolation.hasm/irq_regs.h
Detected Declarations
struct irq_countsenum stats_per_groupfunction hardlockup_count_showfunction kernel_hardlockup_sysfs_initfunction hardlockup_panic_setupfunction hardlockup_panic_setupfunction arch_touch_nmi_watchdogfunction watchdog_hardlockup_touch_cpufunction watchdog_hardlockup_update_resetfunction is_hardlockupfunction watchdog_hardlockup_kickfunction watchdog_hardlockup_checkfunction watchdog_hardlockup_kickfunction watchdog_hardlockup_stopfunction softlockup_count_showfunction kernel_softlockup_sysfs_initfunction softlockup_panic_setupfunction nowatchdog_setupfunction nosoftlockup_setupfunction watchdog_thresh_setupfunction get_16bit_precisionfunction update_cpustatfunction print_cpustatfunction tabulate_irq_countfunction need_counting_irqsfunction start_counting_irqsfunction stop_counting_irqsfunction print_irq_countsfunction report_cpu_statusfunction update_cpustatfunction start_counting_irqsfunction get_timestampfunction set_sample_periodfunction update_report_tsfunction update_touch_tsfunction touch_softlockup_watchdogfunction touch_softlockup_watchdogfunction touch_all_softlockup_watchdogsfunction fromfunction touch_softlockup_watchdog_syncfunction is_softlockupfunction secondsfunction watchdog_timer_fnfunction watchdog_enablefunction watchdog_disablefunction softlockup_stop_fnfunction softlockup_stop_allfunction softlockup_start_fn
Annotated Snippet
struct irq_counts {
int irq;
u32 counts;
};
static DEFINE_PER_CPU(bool, snapshot_taken);
/* Tabulate the most frequent interrupts. */
static void tabulate_irq_count(struct irq_counts *irq_counts, int irq, u32 counts, int rank)
{
int i;
struct irq_counts new_count = {irq, counts};
for (i = 0; i < rank; i++) {
if (counts > irq_counts[i].counts)
swap(new_count, irq_counts[i]);
}
}
/*
* If the hardirq time exceeds HARDIRQ_PERCENT_THRESH% of the sample_period,
* then the cause of softlockup might be interrupt storm. In this case, it
* would be useful to start interrupt counting.
*/
static bool need_counting_irqs(void)
{
u8 util;
int tail = __this_cpu_read(cpustat_tail);
tail = (tail + NUM_SAMPLE_PERIODS - 1) % NUM_SAMPLE_PERIODS;
util = __this_cpu_read(cpustat_util[tail][STATS_HARDIRQ]);
return util > HARDIRQ_PERCENT_THRESH;
}
static void start_counting_irqs(void)
{
if (!__this_cpu_read(snapshot_taken)) {
kstat_snapshot_irqs();
__this_cpu_write(snapshot_taken, true);
}
}
static void stop_counting_irqs(void)
{
__this_cpu_write(snapshot_taken, false);
}
static void print_irq_counts(void)
{
unsigned int i, count;
struct irq_counts irq_counts_sorted[NUM_HARDIRQ_REPORT] = {
{-1, 0}, {-1, 0}, {-1, 0}, {-1, 0}, {-1, 0}
};
if (__this_cpu_read(snapshot_taken)) {
for_each_active_irq(i) {
count = kstat_get_irq_since_snapshot(i);
tabulate_irq_count(irq_counts_sorted, i, count, NUM_HARDIRQ_REPORT);
}
/*
* Outputting the "watchdog" prefix on every line is redundant and not
* concise, and the original alarm information is sufficient for
* positioning in logs, hence here printk() is used instead of pr_crit().
*/
printk(KERN_CRIT "CPU#%d Detect HardIRQ Time exceeds %d%%. Most frequent HardIRQs:\n",
smp_processor_id(), HARDIRQ_PERCENT_THRESH);
for (i = 0; i < NUM_HARDIRQ_REPORT; i++) {
if (irq_counts_sorted[i].irq == -1)
break;
printk(KERN_CRIT "\t#%u: %-10u\tirq#%d\n",
i + 1, irq_counts_sorted[i].counts,
irq_counts_sorted[i].irq);
}
/*
* If the hardirq time is less than HARDIRQ_PERCENT_THRESH% in the last
* sample_period, then we suspect the interrupt storm might be subsiding.
*/
if (!need_counting_irqs())
stop_counting_irqs();
}
}
static void report_cpu_status(void)
{
print_cpustat();
print_irq_counts();
Annotation
- Immediate include surface: `linux/cpu.h`, `linux/init.h`, `linux/irq.h`, `linux/irqdesc.h`, `linux/kernel_stat.h`, `linux/kvm_para.h`, `linux/math64.h`, `linux/mm.h`.
- Detected declarations: `struct irq_counts`, `enum stats_per_group`, `function hardlockup_count_show`, `function kernel_hardlockup_sysfs_init`, `function hardlockup_panic_setup`, `function hardlockup_panic_setup`, `function arch_touch_nmi_watchdog`, `function watchdog_hardlockup_touch_cpu`, `function watchdog_hardlockup_update_reset`, `function is_hardlockup`.
- Atlas domain: Core OS / Scheduler, Processes, Timers, Sync, And Syscalls.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.