NUC980开发板线程内使用SPI通信致CPU占用100% 求日志解读
问题背景
- 运行环境:NUC980开发板,内核版本4.4.289
- 业务逻辑:独立采集线程通过两路SPI接口对接传感器做数据采集
- 异常现象:采集线程CPU占用率达100%
- 已做操作:开启内核追踪宏捕获异常日志,无法解读根因,需要日志解读方法与排查方向
- 参考截图:

异常内核日志
INFO: task acq_md->rawmt:16140 blocked for more than 60 seconds. Not tainted 4.4.289 #10 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. acq_md->rawmt D c03bcc30 0 16140 16106 0x00000000 Backtrace: [<c03bc990>] (__schedule) from [<c03bcfcc>] (schedule+0x50/0xb0) r10:b5b33e70 r9:c3a99c14 r8:ffffffff r7:00000002 r6:c20b0000 r5:c389d300 r4:c20b0000 [<c03bcf7c>] (schedule) from [<c03bd2f8>] (schedule_preempt_disabled+0x18/0x24) r4:c3a99c10 r3:c20b0000 [<c03bd2e0>] (schedule_preempt_disabled) from [<c03bea90>] (__mutex_lock_slowpath+0x94/0x178) [<c03be9fc>] (__mutex_lock_slowpath) from [<c03bebac>] (mutex_lock+0x38/0x3c) r9:c3a987d0 r8:c3a99c10 r7:c3a99c00 r6:c3a4dc00 r5:b5b33e70 r4:80016b01 [<c03beb74>] (mutex_lock) from [<c0239b60>] (spidev_ioctl+0xac/0x6d4) [<c0239ab4>] (spidev_ioctl) from [<c00cb83c>] (do_vfs_ioctl+0x43c/0x660) r10:b5b33e70 r9:c3a987d0 r8:00000010 r7:b5b33e70 r6:00000010 r5:c2033aa0 r4:c2033aa1 [<c00cb400>] (do_vfs_ioctl) from [<c00cba9c>] (SyS_ioctl+0x3c/0x64) r10:00000000 r9:c20b0000 r8:00000010 r7:b5b33e70 r6:80016b01 r5:c2033aa0 r4:c2033aa1 [<c00cba60>] (SyS_ioctl) from [<c000fda0>] (ret_fast_syscall+0x0/0x3c) r8:c000ff88 r7:00000036 r6:00000000 r5:b5b33e70 r4:80016b01 r3:00000000
日志关键信息解读
- 告警触发源:内核hung task检测机制触发,提示PID为16140的
acq_md->rawmt线程处于*不可中断睡眠状态(D状态)*超过60秒。注意该状态下线程不会占用CPU运行,观测到的100% CPU占用是锁异常导致的调度统计偏差,或是其他持锁线程的忙等表现。 - 调用链回溯(从用户态到内核态卡点顺序):用户态线程发起SPI ioctl调用 -> 进入内核spidev字符设备驱动的
spidev_ioctl处理函数 -> 函数内调用mutex_lock申请SPI操作互斥锁 -> 锁已被其他路径持有,进入互斥锁慢等队列 -> 调度器切出该线程,线程持续等待锁释放,超过60秒触发告警。 - 核心故障点:SPI子系统的操作互斥锁被长期持有未释放,导致访问SPI的线程永久阻塞。
问题排查方向
- 应用层逻辑排查:确认两路SPI的设备节点访问逻辑,是否存在多线程/多进程无保护并发访问同一个spidev节点的情况;检查SPI传输相关的错误处理分支,是否存在异常退出时未关闭SPI fd、未触发驱动解锁的路径。
- 驱动逻辑排查:检查NUC980平台SPI控制器驱动、spidev驱动的实现,重点确认互斥锁的加锁/解锁配对情况,尤其是传输超时、硬件报错等异常分支是否存在漏解锁问题;确认两路SPI是否共用同一个控制器实例的全局锁,是否存在锁递归申请导致的死锁。
- 内核调试手段:重新编译内核开启锁调试配置,打开
CONFIG_DEBUG_MUTEXES、CONFIG_LOCKDEP、CONFIG_DETECT_HUNG_TASK的详细栈打印选项,复现问题时内核会直接打印持锁线程的调用栈,直接定位未释放锁的代码路径;问题复现时可遍历/proc/*/stack查找处于SPI驱动路径内的持锁线程。 - 硬件链路排查:用示波器测量两路SPI的CLK、CS、MISO、MOSI引脚电平,确认是否存在传感器硬件故障、引脚虚焊/短路、电平不匹配导致SPI控制器一直处于忙等传输完成的状态,持锁不释放。
内容的提问来源于stack exchange,提问作者Mr.bear
相关产品推荐
相关产品推荐

