watchdog 调用流程(hang住之后)

本文是已经假设了,userspace一直有喂狗操作,但是当系统出现crash,hang住之后,watchdog call flow

watchdog call flow

  系统 hang

    │

    │  没有人调用 qcom_wdt_ping()

    │  没有人 writel(1, WDT_RST)

    │

    │  等待 (timeout - pretimeout) 秒

    │  = 10 - 1 = 9秒(你的配置)

    │

    ▼

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  【BARK 阶段】硬件触发中断

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

    │

    ▼

  qcom_wdt_isr()                        # qcom-wdt.c:65

    │  硬件 GIC_SPI 0 中断触发

    │  struct watchdog_device *wdd = arg;

    │

    ▼

  watchdog_notify_pretimeout(wdd)        # watchdog_pretimeout.c:102

    │  spin_lock_irqsave()

    │  wdd->gov->pretimeout(wdd)        ← 调用当前 governor

    │

    ▼

  pretimeout_panic()                     # pretimeout_panic.c

    │  panic("watchdog pretimeout event\n")

    │

    ▼

  panic()                                # kernel/panic.c

    │  打印 call stack

    │  emergency_restart()

    │

    ▼ ???(这两个是怎么联系起来的,下面解释)

  qcom_wdt_restart()                     # qcom-wdt.c:117

    │  WDT_BITE_TIME = 128ms

    │  WDT_BARK_TIME = 128ms

    │  WDT_EN = 1

    │  wmb()

    │  mdelay(150)

    │

    │  如果 panic 本身也卡住了:

    │  等待剩余 1 秒(pretimeout=1)

    ▼

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  【BITE 阶段】硬件无条件强制复位

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

    │  WDT_BITE_TIME 到期

    │  不经过内核,硬件直接拉复位线

    │

    ▼

  bootloader

    │  检查 TCSR 寄存器

    │  download_mode=full → 进入 9008

    ▼

  PCAT/QFIL 收集 dump

 

  ---

  时间线(你的配置 RuntimeWatchdogSec=10)

  T+0s  : hang 发生,停止 ping

  T+9s  : BARK → qcom_wdt_isr → panic

  T+10s : BITE → 硬件强制复位(兜底)

  T+10s+: bootloader → 9008

Panic的代码流程是如何调用到qcom_watchdog_restart

https://elixir.bootlin.com/linux/v6.6/source/kernel/notifier.c#L225

atomic_notifier_call_chain

遍历到的watchdog相关的

https://elixir.bootlin.com/linux/v6.6/source/drivers/watchdog/watchdog_core.c#L319

这是当时注册的

提问:为什么要有pretimeout

只有 timeout(无 pretimeout)的问题

  T+0s  : hang 发生

  T+10s : BITE → 硬件强制复位

            │

            └─ 内核完全没有机会做任何事

               ✗ 没有 panic log

               ✗ 没有 call stack

               ✗ 没有 ramdump 上下文保存

               ✗ 直接硬件复位,dump 可能不完整

  有 pretimeout 的好处

  T+0s  : hang 发生

  T+9s  : BARK → pretimeout 中断触发

            │

            └─ 内核还活着,有机会:

               ✓ 打印 panic log 和 call stack

               ✓ 保存 CPU 寄存器现场

               ✓ 触发 ramdump 回调,写入 DDR

               ✓ 通知 SCM 准备 dump

            │

  T+10s : BITE → 硬件强制复位(兜底)

            └─ 即使 panic 流程也卡住了,硬件保证一定复位

 

  ---

  本质区别

  ┌────────────────┬──────────────

  │                │ 只有 timeout │ timeout + pretimeout

  ├────────────────┼──────────────

  │ 复位保证       │ ✓ 硬件保证   │ ✓ 硬件保证          

  ├────────────────┼──────────────

  │ panic log      │ ✗ 无         │ ✓ 有                

  ├────────────────┼──────────────

  │ call stack     │ ✗ 无         │ ✓ 有                

  ├────────────────┼──────────────

  │ ramdump 完整性 │ ✗ 可能不完整 │ ✓ 更完整            

  ├────────────────┼──────────────

  │ 调试信息       │ ✗ 几乎没有   │ ✓ 丰富              

  └────────────────┴──────────────

  ▎ timeout 保证设备一定会复位,pretimeout 给内核一个"临死前"保存现场的机会。

  两者缺一不可:只有 timeout 能复位但没有 dump,只有 pretimeout 没有 timeout 则复位无法保证。

#嵌入式转岗的难度怎么样##嵌入式##我的求职进度条#
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务