4、内核稳定性:内核Panic、Watchdog、内存管理(OOM、LMK)、文件系统损坏的检测与恢复
内核稳定性,说白了就是系统的最后一道防线。用户空间崩了,我们还能重启进程。内核崩了?那手机就直接黑屏重启了。我这些年处理过的稳定性问题里,内核相关的往往是最难啃的骨头。
今天咱们就聊聊内核稳定性的四个核心话题:Panic、Watchdog、内存管理、文件系统。每个都是硬茬子。
4.1 内核Panic:系统最后的“遗言”
内核Panic是什么?就是内核遇到了无法恢复的错误,决定自杀。它会打印一堆信息,然后挂死或重启。
我个人习惯,拿到一个Panic问题,第一件事就是看console-ramoops或pstore里的日志。这些是内核在临死前写进保留内存的“遗言”。
关键信息提取点:
- Panic 字符串:比如“Kernel panic - not syncing: Fatal exception”。告诉你原因。
- 调用栈:哪个函数触发的?这是定位的起点。
- CPU 寄存器:PC指针、LR寄存器,能帮你还原现场。
- 模块信息:如果是驱动模块,会打印模块名和地址。
举个例子,我遇到过一个问题:手机待机时随机重启。抓了十几次pstore,发现每次Panic的调用栈都不一样。嗯,这就有意思了。后来排查发现是DMA内存越界,写坏了内核的链表结构。这种问题,光看一次Panic日志是不够的,得做统计分析。
我的调试技巧:
在userdebug版本里,我会打开CONFIG_PANIC_ON_OOPS和CONFIG_PANIC_TIMEOUT。这样内核在遇到Oops时也会直接Panic,并自动重启。配合pstore,能抓到更完整的现场。
4.2 Watchdog:系统“心跳”的守护者
Watchdog分两种:硬件Watchdog和软件Watchdog。Android里最常见的是内核软锁检测(soft lockup)和硬锁检测(hard lockup)。
软锁是什么?一个CPU核长时间处于内核态,不调度。比如某个驱动在自旋锁里死循环了。硬锁更严重,连中断都被关了。
我记得有一次,客户反馈手机播放视频时概率性死机。抓日志发现是soft lockup,CPU0卡在msm_vidc驱动里。为什么?因为视频解码时,一个缓冲区没及时释放,导致驱动在等待一个永远不会来的中断。
Watchdog的配置参数,我列个表:
| 参数 | 默认值 | 说明 |
|---|---|---|
softlockup_panic |
0 | 软锁时是否触发Panic。建议设为1 |
nmi_watchdog |
1 | 是否启用NMI Watchdog检测硬锁 |
watchdog_thresh |
10 | 超时阈值,单位秒 |
注意:量产机上softlockup_panic建议打开。虽然会触发重启,但总比手机卡死在那里强。用户能接受重启,但接受不了“死机”。
4.3 内存管理:OOM与LMK的博弈
Android的内存管理,说白了就是“抢资源”。应用抢,系统服务抢,内核也在抢。抢不过怎么办?杀进程。
OOM Killer是内核的“最后手段”。当系统内存极度紧张时,内核会遍历所有进程,算一个badness分数,分数最高的就被杀了。
但OOM Killer有个问题:它杀进程时,系统可能已经卡顿很久了。所以Android引入了LMK(Low Memory Killer),后来演进到LMKD。它会在内存水位线到达之前,提前杀掉低优先级的进程。
我曾经遇到一个案例:手机玩游戏时,后台的微信被杀了。用户很生气。查日志发现,LMKD把微信的oom_score_adj设得太高了。为什么?因为微信后台有个定位服务在持续唤醒CPU,被LMKD判定为“耗电大户”。
解决方案?嗯,我们调整了LMKD的minfree参数,给前台应用留了更多内存空间。同时也和微信团队沟通,优化了后台定位的逻辑。
关键文件与节点:
/proc/sys/vm/min_free_kbytes:保留内存大小/sys/module/lowmemorykiller/parameters/minfree:LMK各等级阈值/proc/pid/oom_score_adj:进程的OOM权重,范围[-1000, 1000]/proc/pressure/memory:PSI内存压力信息,LMKD依赖它做决策
你想想看,如果min_free_kbytes设得太小,系统容易OOM。设得太大,可用内存就少了。这个值怎么定?我一般建议是总内存的2%~3%。比如6GB内存,设120MB~180MB。
4.4 文件系统损坏:检测与恢复
文件系统损坏,是内核稳定性里最让人头疼的问题之一。因为它不像Panic那样有明确的调用栈,也不像OOM那样有日志可查。它往往是“静默”的——直到你读写某个文件时,才发现数据已经坏了。
Android里最常用的文件系统是ext4和f2fs。我个人的经验是,f2fs在闪存上表现更好,但损坏后恢复难度更大。
文件系统损坏的原因,我总结了几类:
- 意外掉电:写操作进行到一半,突然断电。
- 驱动Bug:eMMC/UFS驱动返回了错误的数据。
- 硬件故障:闪存坏块增多,导致元数据损坏。
- 内核Bug:比如VFS层的并发问题。
检测手段呢?
- 开机时强制fsck:如果文件系统标记为“脏”,系统会在开机时自动检查。
- 内核日志:搜索“EXT4-fs error”或“F2FS-fs error”。
- dmesg:很多文件系统错误会打印在dmesg里。
我记得有一次,某款手机升级系统后,大量用户反馈“存储空间不足”。查了半天,发现是f2fs的垃圾回收机制出了问题,导致大量无效数据占用了空间。最后通过fsck.f2fs -f强制修复才解决。
避坑指南:
我曾经在调试时,直接对挂载中的文件系统跑fsck,结果把系统搞崩了。记住:文件系统检查必须在umount状态下进行。对于系统分区,可以在recovery模式下操作。
最后说一句,内核稳定性没有银弹。每个问题都要结合具体的硬件平台、内核版本、驱动代码来分析。但掌握了Panic、Watchdog、内存管理、文件系统这四块,你就有了80%的武器库。剩下的,就是经验和耐心了。