瑞芯微平台嵌入式系统启动后do_page_fault问题求助
瑞芯微平台内核自旋锁触发页错误问题分析
从提供的内核栈回溯信息来看,崩溃的核心调用路径是:
vop_isr -> pm_runtime_get_if_in_use -> _raw_spin_lock_irqsave
在调用自旋锁函数时触发了数据中止(DataAbort),也就是内核态页错误。你尝试替换不同的自旋锁变体(spin_lock_irq/_raw_spin_lock_irq)后问题依旧,这说明问题根源不在自旋锁的具体类型,而有更深层的原因:
为什么自旋锁会触发页错误?
自旋锁本身的实现不会引发页错误——它只是对内存中的锁变量做原子操作。触发页错误的本质是自旋锁要访问的锁变量所在的内存地址不可用,可能的情况包括:
- 锁变量所在的内存页被错误释放、离线,或者从未被正确映射
- 锁变量属于某个设备结构体,但该结构体已被销毁,而中断仍在触发
- 低功耗状态下,锁变量所在的内存域被断电,导致物理内存不可访问
结合你的栈回溯,这个锁变量大概率属于PM runtime的设备电源管理结构体(比如struct device里的power.lock),问题出在VOP中断触发时,这个结构体的内存已经不可访问了。
换自旋锁函数没用的原因
不管是_raw_spin_lock_irqsave、spin_lock_irq还是_raw_spin_lock_irq,它们的第一步操作都是要读取/修改锁变量的内存值。只要锁变量的地址无效,任何自旋锁函数都会触发页错误——你替换的只是自旋锁的中断处理逻辑,并没有解决锁变量本身不可访问的核心问题。
可能的根因方向
- PM runtime与中断的竞态:VOP设备进入runtime suspend后,相关内存被断电或释放,但中断没有被正确屏蔽,导致中断触发后访问无效内存。栈回溯中出现
cpuidle_enter_state,说明崩溃发生在CPU进入idle低功耗状态时,这种竞态的概率更高。 - 设备生命周期管理错误:VOP设备的结构体被提前释放,但中断处理函数没有被注销,导致中断触发时访问已释放的内存。
- 内存配置错误:内核内存被错误标记为可交换(内核内存默认不可交换),或者DMA/内存映射操作导致锁变量的虚拟地址映射失效。
- 内核版本bug:你使用的4.19.111内核,瑞芯微的补丁可能存在VOP或PM runtime相关的bug,比如低功耗状态下内存域管理不当。
排查建议
- 临时禁用VOP设备的PM runtime功能,观察是否还会触发崩溃,验证问题是否与PM相关。
- 检查VOP设备的中断屏蔽逻辑:确认设备进入suspend状态时,是否正确屏蔽了对应的中断源。
- 查看崩溃前的内核日志,寻找VOP设备的suspend/resume日志,是否有异常报错。
- 确保锁变量所在的内存页被固定(比如使用内核内存标记),避免被换出或释放。
- 查阅瑞芯微官方针对4.19.111版本的补丁,是否有VOP或PM runtime相关的bug修复。
内容的提问来源于stack exchange,提问作者leowinchester
相关产品推荐
相关产品推荐

