lockdep_hardirq_threaded() is supposed to be used within IRQ core code
and not within drivers. It is not obvious from within the driver, that
this is the only interrupt service routing and that it is not shared
handler.
Replace lockdep_hardirq_threaded() with a lockdep annotation limiting
threaded context on PREEMPT_RT to __vmbus_isr().
Fixes: f8e6343b7a89c ("Drivers: hv: vmbus: Use kthread for vmbus interrupts on
PREEMPT_RT")
Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
---
drivers/hv/vmbus_drv.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 23206640c6139..44877664d9d08 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1384,8 +1384,19 @@ void vmbus_isr(void)
if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
vmbus_irqd_wake();
} else {
- lockdep_hardirq_threaded();
+ static DEFINE_WAIT_OVERRIDE_MAP(vmbus_map, LD_WAIT_CONFIG);
+
+ /*
+ * vmbus_isr is never force-threaded and always invoked at hard
+ * IRQ level. __vmbus_isr() below can acquire a spinlock_t
+ * which becomes a sleeping lock and must not be acquired in
+ * this context. Therefore on PREEMPT_RT this will be threaded
+ * via vmbus_irqd_wake(). On non-PREEMPT the annotation lets
+ * lockdep know that acquiring a spinlock_t is not an issue.
+ */
+ lock_map_acquire_try(&vmbus_map);
__vmbus_isr();
+ lock_map_release(&vmbus_map);
}
}
EXPORT_SYMBOL_FOR_MODULES(vmbus_isr, "mshv_vtl");
--
2.53.0