Linux kernel lockdep在抢占rt linux内核中有用吗?

Linux kernel lockdep在抢占rt linux内核中有用吗?,linux-kernel,preempt-rt,Linux Kernel,Preempt Rt,我为linux内核修补了4.14.103-rt55抢占rt补丁。并通过设置Y为 CONFIG_UNINLINE_SPIN_UNLOCK=y CONFIG_DEBUG_RT_MUTEXES=y CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_LOCK_ALLOC=y CONFIG_PROVE_LOCKING=y CONFIG_LOCKDEP=y CONFIG_PROVE_RCU=y 我得到了锁数据不一致的lockdep警告:

我为linux内核修补了4.14.103-rt55抢占rt补丁。并通过设置Y为

CONFIG_UNINLINE_SPIN_UNLOCK=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_PROVE_LOCKING=y
CONFIG_LOCKDEP=y
CONFIG_PROVE_RCU=y
我得到了锁数据不一致的lockdep警告:

====================================================
警告:锁定状态不一致
4.14.98-rt55#1污染:G S\ 不一致的{HARDIRQ-ON-W}->{IN-HARDIRQ-W}用法。
cpuhp/0/17[HC1:SC0[0]:HE0:SE1]需要:
((pendingb_lock).lock){?+.},位于:[]队列工作在+0x6c/0x150上
{HARDIRQ-ON-W}状态注册于:
锁定获取+0x244/0x274
旋转锁定+0x50/0x64
+0x70/0x15c上的队列延迟工作
初始内部构件+0x13c/0x258
内核初始化可释放+0x13c/0x2bc
内核初始化+0x18/0x114
从叉子返回+0x10/0x18
irq事件戳:180
硬件上次启用时间为(179):[]可靠的irq cpu启动+0x164/0x16c
最后一次在(180)处禁用硬盘驱动器:[]el1_irq+0x7c/0x144
上次在(0)启用的软件IRQ:[]复制进程.isra.6.part.7+0x4c8/0x17ec
上次禁用软件IRQ的时间为(0):[<(null)>](null)

其他可能有助于我们调试的信息:
可能的不安全锁定场景:

CPU0
----
锁((pendingb_锁)。锁)

锁((pendingb_锁)。锁)

***死锁***

cpuhp/0/17持有的1把锁:
#0:(cpuhp_状态更新){++.},位于:[]cpuhp_线程_fun+0xd4/0x1e0

堆栈回溯:
CPU:0 PID:17通信:cpuhp/0污染:G S 4.14.98-rt55#1
硬件名称:电路板(DT)
呼叫跟踪:
[]转储\u回溯+0x0/0x240
[]显示\u堆栈+0x24/0x30
[]转储堆栈+0x94/0xd0
[]打印使用错误+0x1e8/0x29c
[]标记锁定+0x40c/0x618
[]锁定获取+0x3dc/0x14e4
[]锁定获取+0x244/0x274
[]rt_自旋锁+0x50/0x64
[]队列工作在+0x6c/0x150上
[]可靠的队列nop+0x9c/0xdc
[]可靠的irq处理程序+0xb0/0x1e0
[]处理设备irq+0x23c/0x478
[]处理自定义ipi irq+0x6c/0x70
[]通用句柄irq+0x2c/0x44
[]句柄域irq+0xf0/0xf4
[]句柄\u IPI+0x194/0x3a8
[]gic_handle_irq+0x160/0x164
异常堆栈(0xFFFF800A70BA90到0xffffff800a70bbd0)
ba80:FFFFFF C0F953B680 FFFFFFFF 8009E9C1C8
baa0:FFFFFFFFFFFFFFEB0 000000000000FFFFFFFFFF80095B5000 ffffff80095b51e8
bac0:ffffff80097ac1bc 0000000000009645 0000000000000000000000000000009643
bae0:0000000000009644 FFFFFF 80097AC1BC 00000000000000 28 000000 40F6CD4000
bb00:FFFFFF 80095C4880 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
bb20:000000000000000000000000000000000000 FFFFFF 8008C8B3B1 FFFFFF C0F111A180
bb40:0000000000000 140 ffffff8008f9f291 00000000000000 54 FFFFFFFF800915F8D0
bb60:ffffff80088de39c 00000040F6CD40000000000000000000 ffffff800a70bcd0
bb80:ffffff80088de500 FFFFFFFF800A70BCD0 ffffff80088de504 00000000 60C00145
bba0:ffffff8008126c30 0000000000000 1C0 FFFFFFFFFFFFFFFFFFC0F276BD48
bbc0:FFFFFF 800A70BCD0 FFFFFF 80088DE504
[]el1_irq+0xbc/0x144
[]可靠的irq cpu up+0x168/0x16c
[]cpuhp调用回调+0x54c/0xe18
[]cpuhp_thread_fun+0xcc/0x1e0
[]smpboot_thread_fn+0x254/0x270
[]kthread+0x124/0x134
[]从叉子上收回+0x10/0x18\

这把挂着的锁是补好的

rt linux/community/0307 workqueue使用本地irq锁而不是irq禁用-.patch

此修补程序使用了本地\u-lock\u-irqsave代替本地\u-irq\u-save,也用于其解锁功能

我从中得到了一些信息,local\u lock*函数不会在抢占rt内核中禁用抢占和中断

所以我理解了lockdep的警告:

  • 处理一个get lock pendingb_lock
  • hardirq中断B
  • 中断B需要获得锁挂起B_锁
  • 然后内核将与A-B-A死锁

    但是,抢占rt内核中断处理程序不应该在线程中而不是在hardirq上下文中执行

    如果中断处理程序线程未获得锁A,则不应将其调度到cpu之外并执行进程A。是否继续?为什么僵局

    lockdep在抢占rt linux内核中有用吗?还是我出了什么事?

    期待您的回复,谢谢