[ 2063.883377] BUG: spinlock recursion on CPU#0, pheriphy_io/1156
[ 2063.889496] lock: 0x847d9b78, .magic: dead4ead, .owner: pheriphy_io/1156, .owner_cpu: 0
[ 2063.897894] CPU: 0 PID: 1156 Comm: pheriphy_io Not tainted 5.10.186+ #262
[ 2063.904940] Stack : 809f0000 80093d28 00000000 00000000 8091ef64 89dd9268 847d8100 80096d40
[ 2063.913629] 00000000 00000000 00000000 5f9a4635 8400ddb4 00000001 8400dd48 5f9a4635
[ 2063.922310] 00000000 00000000 80909538 8400dc08 00000149 8400dc1c 00000000 000022c4
[ 2063.930990] 3584c90c 8400dc1b ffffffff 00000030 809e0000 80000000 00000000 80910000
[ 2063.939670] 80901328 80901300 80a10000 89dd9268 00000000 00000000 00000000 80a70000
[ 2063.948350] ...
[ 2063.950894] Call Trace:
[ 2063.953446] [<8001d738>] show_stack+0x94/0x12c
[ 2063.958071] [<807f7bcc>] dump_stack+0xac/0xe8
[ 2063.962605] [<8008fe0c>] do_raw_spin_lock+0xdc/0x130
[ 2063.967760] [<807f4570>] adc_write_reg+0x30/0x60
[ 2063.972549] [<807f4898>] ingenic_sadc_irq+0x17c/0x1cc
[ 2063.977796] [<8009a8d0>] __handle_irq_event_percpu+0x70/0x1b8
[ 2063.983756] [<8009aa4c>] handle_irq_event_percpu+0x34/0x8c
[ 2063.989443] [<8009aaf0>] handle_irq_event+0x4c/0x8c
[ 2063.994504] [<800a00a8>] handle_level_irq+0xf0/0x1a8
[ 2063.999654] [<80099bc4>] generic_handle_irq+0x3c/0x54
[ 2064.004898] [<80803bc0>] do_IRQ+0x30/0x6c
[ 2064.009054] [<807f3e44>] xburst2_irq_handler+0xc8/0xd8
[ 2064.014381] [<800a1110>] handle_percpu_devid_irq+0xc0/0x1a0
[ 2064.020157] [<80099bc4>] generic_handle_irq+0x3c/0x54
[ 2064.025394] [<80803bc0>] do_IRQ+0x30/0x6c
[ 2064.029553] [<80016764>] handle_int+0x144/0x150
[ 2064.034253] [<8008ff10>] do_raw_spin_unlock+0x44/0x104
[ 2064.039580] [<80803670>] _raw_spin_unlock+0x10/0x44
[ 2064.044638] [<807f50b4>] ingenic_adc_read_raw+0x148/0x220
[ 2064.050241] [<8058e9bc>] iio_read_channel_info+0xbc/0xcc
[ 2064.055751] [<803f1df0>] dev_attr_show+0x24/0x60
[ 2064.060545] [<801ce5a0>] sysfs_kf_seq_show+0xcc/0x158
[ 2064.065789] [<8016e774>] seq_read_iter+0x11c/0x570
[ 2064.070758] [<8013e728>] vfs_read+0x2a4/0x310
[ 2064.075274] [<8013ed48>] ksys_read+0xe0/0x124
[ 2064.079794] [<80028e38>] syscall_common+0x34/0x58
[ 2064.084668]
从log上可以定位到是adc 驱动这块的问题
问题分析
1. 问题本质
BUG: spinlock recursion on CPU#0 - 表示在CPU 0上发生了自旋锁递归
pheriphy_io/1156 - 问题发生在pheriphy_io进程(PID 1156)
自旋锁递归:同一个进程试图重复获取已经持有的自旋锁,导致死锁
2. 堆栈跟踪关键信息
从调用栈可以看出问题路径:
ingenic_adc_read_raw() // 获取锁↓ingenic_sadc_irq() // 中断处理函数↓adc_write_reg() // 再次尝试获取同一个锁
可能的原因
中断重入问题:ADC驱动在中断处理程序中又调用了可能获取锁的函数
锁使用不当:驱动程序没有正确处理中断上下文中的锁
竞态条件:ADC读取和中断处理之间的竞争
解决方案
方案1:检查并修复驱动代码
检查ingenic_adc_read_raw和ingenic_sadc_irq函数中的锁使用:
// 可能的修复方向staticirqreturn_tingenic_sadc_irq(int irq, void *dev_id){// 使用spin_lock_irqsave替代spin_lockunsigned long flags;spin_lock_irqsave(&adc_lock, flags);// 处理逻辑spin_unlock_irqrestore(&adc_lock, flags);return IRQ_HANDLED;}
方案2:更新内核或驱动
# 1. 更新内核sudo apt updatesudo apt upgrade linux-image-$(uname -r)# 2. 或者尝试更新的内核版本sudo apt install linux-image-generic-hwe-20.04# 3. 重启系统sudo reboot方案3:临时禁用或调整ADC驱动# 临时禁用ADC驱动sudo modprobe -r ingenic_adc# 或调整中断处理echo "disable" | sudo tee /proc/irq/XXX/ingenic_adc# 检查相关模块lsmod | grep ingenic
方案4:检查硬件连接
可能是硬件问题导致ADC中断异常:
检查ADC相关硬件的连接
检查电源稳定性
检查是否有硬件短路或损坏
方案5:收集更多调试信息
# 1. 启用更多内核调试echo 8 > /proc/sys/kernel/printk# 2. 收集完整的内核日志sudo dmesg -w > kernel_log.txt &# 3. 使用ftrace追踪sudo trace-cmd record -e spinlock -p function_graph# 4. 检查系统状态cat /proc/interrupts | grep adccat /proc/locks
方案6:调整内核参数
在/etc/sysctl.conf中添加:
# 增加自旋锁调试kernel.spinlock_debug = 1kernel.softlockup_panic = 0# 降低中断频率kernel.watchdog_thresh = 60在Linux中,给cpu发中断,一般正常10ms内得到回应。
紧急恢复方法
如果系统频繁死机,可以先尝试:
# 1. 进入恢复模式# 在GRUB启动时选择恢复模式# 2. 使用旧内核启动# 在GRUB中选择以前的内核版本# 3. 单用户模式排查# 启动时添加内核参数:single 或 init=/bin/bash
推荐排查步骤
首先尝试更新内核(最可能解决问题)
检查是否有特定触发条件(如执行特定操作后必现)
收集完整的内核日志用于开发者分析
考虑报告给内核维护者(Ingenic ADC驱动相关)
这是一个比较严重的驱动bug,可以联系硬件厂商获取修复后的驱动程序。
