限时福利领取


看门狗硬件示意图

看门狗基础原理与日志解析

当内核日志频繁出现[wdtk] kick watchdog时,表明系统正在执行喂狗操作。看门狗本质是一个硬件定时器,其工作流程可分为三个阶段:

  1. 初始化阶段:通过watchdog_init()设置超时时间(通常为30-60秒)
  2. 监控阶段:若未收到喂狗信号,定时器到期会触发系统复位
  3. 喂狗阶段:通过写入特定寄存器(如WDT_CRR)重置计数器

日志中的kick操作对应第三阶段,但频繁出现可能暗示以下问题:

  • 喂狗间隔设置不合理(过短增加系统负载,过长可能导致误触发)
  • 存在并发访问导致喂狗冲突
  • 用户空间与内核空间喂狗策略不一致

硬件vs软件看门狗实现对比

看门狗工作流程

硬件看门狗特点:

  1. 依赖物理定时器电路,复位信号直接连接CPU复位引脚
  2. 超时精度高(误差通常<1%)
  3. 需要底层驱动支持寄存器操作

软件看门狗差异点:

  1. 基于内核定时器实现,受系统调度影响
  2. 可通过/dev/watchdog设备文件控制
  3. 存在竞态条件风险(需用锁保护)

典型并发问题示例:

// 错误示例:无保护的喂狗操作
static void watchdog_kick(void) {
    writel(WDT_CRR, reload_value); // 可能被中断打断
}

// 正确做法:添加自旋锁
static DEFINE_SPINLOCK(wdt_lock);
static void safe_watchdog_kick(void) {
    spin_lock(&wdt_lock);
    writel(WDT_CRR, reload_value);
    spin_unlock(&wdt_lock);
}
时间复杂度:O(1),锁粒度控制在单次寄存器操作

完整代码实现示例

内核模块接口封装

#include <linux/watchdog.h>

static struct mutex wdt_mutex;
static bool watchdog_active;

int watchdog_start(int timeout) {
    mutex_lock(&wdt_mutex);
    if (watchdog_active) {
        mutex_unlock(&wdt_mutex);
        return -EBUSY;
    }

    // 设置硬件超时值
    writel(WDT_TORR, timeout);
    writel(WDT_CRR, WDT_RELOAD_VALUE);
    watchdog_active = true;
    mutex_unlock(&wdt_mutex);
    return 0;
}
EXPORT_SYMBOL(watchdog_start);

用户空间ioctl控制

// 用户态守护进程示例
int main() {
    int fd = open("/dev/watchdog", O_RDWR);
    ioctl(fd, WDIOC_SETTIMEOUT, &timeout); 

    while(1) {
        usleep(2000000); // 喂狗间隔为超时时间的1/3
        ioctl(fd, WDIOC_KEEPALIVE, 0);
    }
}

高精度定时器实现

static enum hrtimer_restart wdt_timer_callback(struct hrtimer *timer) {
    safe_watchdog_kick();
    hrtimer_forward_now(timer, ns_to_ktime(interval_ns));
    return HRTIMER_RESTART;
}

void init_hrtimer(void) {
    struct hrtimer *timer = &wdt_timer;
    hrtimer_init(timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
    timer->function = wdt_timer_callback;
    hrtimer_start(timer, ns_to_ktime(interval_ns), HRTIMER_MODE_REL);
}

生产环境避坑指南

  1. 线程优先级设置
  2. 喂狗线程应设为实时优先级(如SCHED_FIFO)
  3. 避免被普通线程阻塞

  4. 超时公式计算

    看门狗超时 > 最大业务处理周期 × 3
  5. 负载过高降级策略

  6. 当CPU使用率>80%时,动态延长喂狗间隔
  7. 记录喂狗失败次数到sysfs
  8. 触发内存压缩释放资源

延伸思考问题

  1. 在Kubernetes集群中,如何设计DaemonSet确保每个节点的看门狗有效性?
  2. 当系统进入低功耗模式时,看门狗时钟源切换有哪些注意事项?
  3. 如何验证看门狗复位功能不会影响持久化存储的一致性?
Logo

音视频技术社区,一个全球开发者共同探讨、分享、学习音视频技术的平台,加入我们,与全球开发者一起创造更加优秀的音视频产品!

更多推荐