产品大用户场景下运行一段时间即报“Aug 7 19:19:58 localhost kernel: NMI watchdog: BUG: soft lockup - CPU#7 stuck for 23s! [xxxx:80779]" 错误,内核日志调用栈显示是在获取锁时失败,该锁是读写锁,使用read_lock或者write_lock获取锁,锁使用情况如下所示,如图所示锁用在桶深256的HASH表下挂链表插入删除时的竞争保护。刚开始按照用户态经验加锁时锁不可用不是被挂起睡眠吗?等待锁可用再被唤醒,怎么会一直占有CPU20多秒,通过分析内核读写锁函数发现内核读写锁类似spin_lock死等,所以应该是该锁被其他人长时间占用,到了调用栈所示的调用时一直无法获取锁导致的,死等20多秒超时导致该CPU的watchdog发现(watchdog是IRQ所以不会因为死等锁而不能调度),同时可以确定用户态死锁不会导致soft lockup。
结合产品内核代码进而分析可能原因: 1) 多个内核锁的PV操作顺序不当导致死锁; 2) HASH链上的节点太多,导致获取锁的任务处理时间超过20s;3)某任务获取锁之后睡眠(同spin_lock后不能睡眠)4) 其他原因死锁
分析代码排除1,增加调试手段查看所有HASH链的长度排除2,分析代码发现操作HASH表时