什么是 .内核崩溃(任务挂起)中锁名后的(点)和 +(加号)?



我发现当内核检测到task hung时,内核崩溃中有点号和加号。

显示系统中持有的所有锁: 2把锁由孔塔斯德/737持有: #0: (rcu_read_lock){....}, at: [<00000000eaa2e968>] check_hung_uninterruptible_tasks 内核/hung_task.c:175 [inline] #0: (rcu_read_lock){....}, at: [<00000000eaa2e968>] watchdog+0x1c5/0xd60 kernel/hung_task.c:249 #1: (tasklist_lock){.+.+}, at: [<000000005ed461f9>] debug_show_all_locks+0xd3/0x400 kernel/locking/lockdep.c:4464

锁名称后面括号之间的点和加号是什么?

自我回答:

linux 文档中有一个答案。

验证器将锁类使用历史记录跟踪为 4n + 1 个单独的 状态位:

  • "曾经在国家背景下举行">
  • "曾经在状态上下文中作为读取锁持有">
  • "曾经在启用状态的情况下举行">
  • "在启用状态的情况下一直保持为读取锁定">

其中 STATE 可以是以下任一 (kernel/locking/lockdep_states.h) - 哈迪尔克 - 软伊尔克 - reclaim_fs

  • "曾经使用过" [ == !未使用 ]

违反锁定规则时,这些状态位将显示在 锁定错误消息,在卷曲内。一个人为的例子:

modprobe/2287 正在尝试获取 lock:
(&sio_locks[i].lock){-.-...}, at: [] mutex_lock+0x21/0x24

但是任务已经持有 Lock:(&sio_locks[i].lock){-.-...}, at:
[] mutex_lock+0x21/0x24

位位置指示每个状态的状态,状态读取 上面列出,每个字符中显示的字符表示:

'." 在 IRQS 禁用时获取,而不是在 IRQ 上下文中获取 "-" 在 IRQ 上下文中获取 "+" 在启用 IRQS 的情况下获取 "?" 在启用了 IRQ 的 IRQ 上下文中获取。

未使用的互斥锁不能成为错误原因的一部分。

但是内核文档和崩溃日志之间的区别在于崩溃日志中只有 4 位,但文档中有 6 位。
这是因为,出于某种原因,reclaim_fsLinux 源代码树 (v4.16) 的kernel/locking/lockdep_states.h

最新更新