自旋锁调测方法
功能说明
多核环境下,多任务系统使用自旋锁达到互斥访问资源的目的。自旋锁的检测模块(lockdep),能够检测以下几种类型的错误(包括使用错误):
- 重复上锁。
- 死锁,以ABBA为例进行说明:
- 任务A持有自旋锁X,并永久等待自旋锁Y。
- 任务B持有自旋锁Y,并永久等待自旋锁X。
此时任务A和任务B死锁。
- 未持锁情况下释放锁。
- lockdep记录信息溢出。
使用方法
通过配置项LOSCFG_KERNEL_SMP_LOCKDEP打开自旋锁的检测模块lockdep,开启自旋锁调测功能,该宏开关可以通过make menuconfig在菜单项中开启“Enable Spinlock Lockdep Check”使能。
Kernel ---> Enable Kernel SMP ---> Enable Spinlock Lockdep Check
死锁定位实例
- 打开自旋锁检测后,检测到死锁时会打印死锁信息,死锁检测的打印信息示例如下。
图1 死锁模块打印信息
- 复制request addr的值(本例中为0x802a6528),在系统镜像的.asm反汇编文件(默认在Huawei_LiteOS/out/<platform>目录下,其中的platform为具体的平台名)中找到相应的地址,如下图所示,即可定位到调用spinlock的位置及调用函数(本例中为task_fx02)。
图2 反汇编文件中找到对应地址
- 根据图一死锁打印信息中第二个蓝框的自旋锁,通过代码逻辑找到另一个任务持有该锁的情况,再结合代码,调整spinlock调用的时序,从而解决死锁问题。
建议与总结
自旋锁死锁一般发生在某个CPU卡住、任务不再发生调度时。若不开启自旋锁死锁检查,可以使用JLink等调试工具halt住CPU或者触发看门狗异常,查看PC值是否为自旋锁代码,以此确定是否发生了自旋锁死锁。