* [PATCH 0/2] hv: vmbus: Small cleanups @ 2026-04-01 15:15 Sebastian Andrzej Siewior 2026-04-01 15:15 ` [PATCH 1/2] hv: vmbus: Replace lockdep_hardirq_threaded() with lockdep annotation Sebastian Andrzej Siewior 2026-04-01 15:15 ` [PATCH 2/2] hv: vmbus: Remove vmbus_irq_initialized Sebastian Andrzej Siewior 0 siblings, 2 replies; 6+ messages in thread From: Sebastian Andrzej Siewior @ 2026-04-01 15:15 UTC (permalink / raw) To: linux-hyperv, linux-rt-devel Cc: K. Y. Srinivasan, Dexuan Cui, Haiyang Zhang, Jan Kiszka, Long Li, Michael Kelley, Wei Liu, Sebastian Andrzej Siewior Replacing the lockdep_hardirq_threaded() annotation which does not belong in drivers and removing the vmbus_irq_initialized which seems redundant. Sebastian Andrzej Siewior (2): hv: vmbus: Replace lockdep_hardirq_threaded() with lockdep annotation hv: vmbus: Remove vmbus_irq_initialized drivers/hv/vmbus_drv.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) -- 2.53.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] hv: vmbus: Replace lockdep_hardirq_threaded() with lockdep annotation 2026-04-01 15:15 [PATCH 0/2] hv: vmbus: Small cleanups Sebastian Andrzej Siewior @ 2026-04-01 15:15 ` Sebastian Andrzej Siewior 2026-04-04 1:22 ` Michael Kelley 2026-04-01 15:15 ` [PATCH 2/2] hv: vmbus: Remove vmbus_irq_initialized Sebastian Andrzej Siewior 1 sibling, 1 reply; 6+ messages in thread From: Sebastian Andrzej Siewior @ 2026-04-01 15:15 UTC (permalink / raw) To: linux-hyperv, linux-rt-devel Cc: K. Y. Srinivasan, Dexuan Cui, Haiyang Zhang, Jan Kiszka, Long Li, Michael Kelley, Wei Liu, Sebastian Andrzej Siewior 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 <bigeasy@linutronix.de> --- drivers/hv/vmbus_drv.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index bc4fc1951ae1c..e44275370ac2a 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -1407,8 +1407,11 @@ 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); + + lock_map_acquire_try(&vmbus_map); __vmbus_isr(); + lock_map_release(&vmbus_map); } } EXPORT_SYMBOL_FOR_MODULES(vmbus_isr, "mshv_vtl"); -- 2.53.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* RE: [PATCH 1/2] hv: vmbus: Replace lockdep_hardirq_threaded() with lockdep annotation 2026-04-01 15:15 ` [PATCH 1/2] hv: vmbus: Replace lockdep_hardirq_threaded() with lockdep annotation Sebastian Andrzej Siewior @ 2026-04-04 1:22 ` Michael Kelley 2026-07-15 14:32 ` Sebastian Andrzej Siewior 0 siblings, 1 reply; 6+ messages in thread From: Michael Kelley @ 2026-04-04 1:22 UTC (permalink / raw) To: Sebastian Andrzej Siewior, linux-hyperv@vger.kernel.org, linux-rt-devel@lists.linux.dev Cc: K. Y. Srinivasan, Dexuan Cui, Haiyang Zhang, Jan Kiszka, Long Li, Wei Liu From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Sent: Wednesday, April 1, 2026 8:15 AM > Nit: For historical consistency, use "Drivers: hv: vmbus:" as the prefix for the patch "Subject:" line. Same in Patch 2 of this series. Also, any reason not to have copied linux-kernel@vger.kernel.org? I know this is pretty much just a Hyper-V thing, but I would have liked to see what the Sashiko AI did with these two patches. :-) > 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. I presume you meant "routine". And what do you mean by "the only interrupt service routine"? And why is the lack of obviousness relevant here? I don't have deep expertise in lockdep, but evidently there's some conclusion to reach and it would have helped me to have it spelled out. > > Replace lockdep_hardirq_threaded() with a lockdep annotation limiting > threaded context on PREEMPT_RT to __vmbus_isr(). Again, I'm not clear what "limiting threaded context" means. But see my additional comment further down. > > Fixes: f8e6343b7a89c ("Drivers: hv: vmbus: Use kthread for vmbus interrupts on PREEMPT_RT") > Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> > --- > drivers/hv/vmbus_drv.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c > index bc4fc1951ae1c..e44275370ac2a 100644 > --- a/drivers/hv/vmbus_drv.c > +++ b/drivers/hv/vmbus_drv.c > @@ -1407,8 +1407,11 @@ void vmbus_isr(void) > if (IS_ENABLED(CONFIG_PREEMPT_RT)) { > vmbus_irqd_wake(); > } else { > - lockdep_hardirq_threaded(); I see two similar occurrences of LD_WAIT_CONFIG in the kernel: __kfree_rcu_sheaf() and adjacent to printk_legacy_allow_spinlock_enter(). Both occurrences have a multi-line comment explaining the "why". I'd like to see a similar comment here so that drive-by readers of the code have some idea of what's going on. My suggestion is something like this: vmbus_isr() always runs at hard IRQ level -- the interrupt is not threaded. It calls __vmbus_isr() here, which may obtain the spinlock_t sched_lock for a VMBus channel in vmbus_chan_sched(). If CONFIG_PROVE_LOCKING=y, lockdep complains because obtaining spinlock_t's is not permitted at hard IRQ level in PREEMPT_RT configurations. However, the PREEMPT_RT path is handled separately above, so there's actually not a problem. Tell lockdep that acquiring the spinlock_t is valid by temporarily raising the wait-type to LD_WAIT_CONFIG using the "fake" lock vmbus_map. If lockdep is not enabled, the acquire & release of the fake lock are no-ops, so performance is not impacted. Please review my suggested text and revise as appropriate, as I'm far from an expert on any of this. The above is based on what I've learned just now from a bit of research. And thanks for jumping in and making all this better .... Michael > + static DEFINE_WAIT_OVERRIDE_MAP(vmbus_map, LD_WAIT_CONFIG); > + > + lock_map_acquire_try(&vmbus_map); > __vmbus_isr(); > + lock_map_release(&vmbus_map); > } > } > EXPORT_SYMBOL_FOR_MODULES(vmbus_isr, "mshv_vtl"); > -- > 2.53.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: RE: [PATCH 1/2] hv: vmbus: Replace lockdep_hardirq_threaded() with lockdep annotation 2026-04-04 1:22 ` Michael Kelley @ 2026-07-15 14:32 ` Sebastian Andrzej Siewior 0 siblings, 0 replies; 6+ messages in thread From: Sebastian Andrzej Siewior @ 2026-07-15 14:32 UTC (permalink / raw) To: Michael Kelley Cc: linux-hyperv@vger.kernel.org, linux-rt-devel@lists.linux.dev, K. Y. Srinivasan, Dexuan Cui, Haiyang Zhang, Jan Kiszka, Long Li, Wei Liu On 2026-04-04 01:22:08 [+0000], Michael Kelley wrote: > Nit: For historical consistency, use "Drivers: hv: vmbus:" as the prefix for the > patch "Subject:" line. Same in Patch 2 of this series. okay. > Also, any reason not to have copied linux-kernel@vger.kernel.org? I know this > is pretty much just a Hyper-V thing, but I would have liked to see what the > Sashiko AI did with these two patches. :-) Can do. > > 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. > > I presume you meant "routine". And what do you mean by "the only interrupt > service routine"? And why is the lack of obviousness relevant here? I don't have > deep expertise in lockdep, but evidently there's some conclusion to reach and it > would have helped me to have it spelled out. You use lockdep_hardirq_threaded() which marks the hardirq as a thread for lockdep purposes. The reason is that the IRQ core will force-thread the handler and the whole routine will be threaded. It does invoke the function and the very begin and nothing else will be done. vmbus_isr() is using it before __vmbus_isr() is invoked and there can be other functions/ ISRs that are invoked afterwards which would be wrongly recognized. To make it more concrete: sysvec_hyperv_callback() invokes mshv_handler and vmbus_handler. Would vmbus_handler() be invoked first then it will "spill" this lockdep attribute into mshv_handler(). Nested locks in mshv_handler() would not be visible then. This override limits it only to __vmbus_isr() while the RT case above is using vmbus_irqd_wake(). > > > > Replace lockdep_hardirq_threaded() with a lockdep annotation limiting > > threaded context on PREEMPT_RT to __vmbus_isr(). > > Again, I'm not clear what "limiting threaded context" means. But see my > additional comment further down. Does the explanation above make it clear? > > > > Fixes: f8e6343b7a89c ("Drivers: hv: vmbus: Use kthread for vmbus interrupts on PREEMPT_RT") > > Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> > > --- > > drivers/hv/vmbus_drv.c | 5 ++++- > > 1 file changed, 4 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c > > index bc4fc1951ae1c..e44275370ac2a 100644 > > --- a/drivers/hv/vmbus_drv.c > > +++ b/drivers/hv/vmbus_drv.c > > @@ -1407,8 +1407,11 @@ void vmbus_isr(void) > > if (IS_ENABLED(CONFIG_PREEMPT_RT)) { > > vmbus_irqd_wake(); > > } else { > > - lockdep_hardirq_threaded(); > > I see two similar occurrences of LD_WAIT_CONFIG in the kernel: > __kfree_rcu_sheaf() and adjacent to printk_legacy_allow_spinlock_enter(). > Both occurrences have a multi-line comment explaining the "why". I'd like > to see a similar comment here so that drive-by readers of the code have > some idea of what's going on. My suggestion is something like this: > > vmbus_isr() always runs at hard IRQ level -- the interrupt is not threaded. It > calls __vmbus_isr() here, which may obtain the spinlock_t sched_lock for > a VMBus channel in vmbus_chan_sched(). If CONFIG_PROVE_LOCKING=y, > lockdep complains because obtaining spinlock_t's is not permitted at hard > IRQ level in PREEMPT_RT configurations. However, the PREEMPT_RT path > is handled separately above, so there's actually not a problem. Tell > lockdep that acquiring the spinlock_t is valid by temporarily raising > the wait-type to LD_WAIT_CONFIG using the "fake" lock vmbus_map. > If lockdep is not enabled, the acquire & release of the fake lock are no-ops, > so performance is not impacted. > > Please review my suggested text and revise as appropriate, as I'm far > from an expert on any of this. The above is based on what I've learned > just now from a bit of research. What about? 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. > And thanks for jumping in and making all this better .... so I've been looking at __vmbus_isr() and vmbus_chan_sched() seems fine. vmbus_message_sched() on the handler invokes hv_stimer0_isr() which should not be done in the thread but in the hardirq. Is this the only timer in the system or some legacy thingy that is no longer used? And there is a lot of tasklet involved which mandates a local_bh_disable()/enable() in run_vmbus_irqd() around the function or everything gets pushed into ksoftirqd. > Michael Sebastian ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2] hv: vmbus: Remove vmbus_irq_initialized 2026-04-01 15:15 [PATCH 0/2] hv: vmbus: Small cleanups Sebastian Andrzej Siewior 2026-04-01 15:15 ` [PATCH 1/2] hv: vmbus: Replace lockdep_hardirq_threaded() with lockdep annotation Sebastian Andrzej Siewior @ 2026-04-01 15:15 ` Sebastian Andrzej Siewior 2026-04-04 1:22 ` Michael Kelley 1 sibling, 1 reply; 6+ messages in thread From: Sebastian Andrzej Siewior @ 2026-04-01 15:15 UTC (permalink / raw) To: linux-hyperv, linux-rt-devel Cc: K. Y. Srinivasan, Dexuan Cui, Haiyang Zhang, Jan Kiszka, Long Li, Michael Kelley, Wei Liu, Sebastian Andrzej Siewior vmbus_irq_initialized is only true if the registration of the per-CPU threads succeeded. If it failed, the whole registration aborts and the vmbus_exit() path is never called. Remove vmbus_irq_initialized. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- drivers/hv/vmbus_drv.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index e44275370ac2a..7417841cd1f70 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -1392,8 +1392,6 @@ static void run_vmbus_irqd(unsigned int cpu) __vmbus_isr(); } -static bool vmbus_irq_initialized; - static struct smp_hotplug_thread vmbus_irq_threads = { .store = &vmbus_irqd, .setup = vmbus_irqd_setup, @@ -1513,11 +1511,10 @@ static int vmbus_bus_init(void) * the VMbus interrupt handler. */ - if (IS_ENABLED(CONFIG_PREEMPT_RT) && !vmbus_irq_initialized) { + if (IS_ENABLED(CONFIG_PREEMPT_RT)) { ret = smpboot_register_percpu_thread(&vmbus_irq_threads); if (ret) goto err_kthread; - vmbus_irq_initialized = true; } if (vmbus_irq == -1) { @@ -1561,10 +1558,8 @@ static int vmbus_bus_init(void) else free_percpu_irq(vmbus_irq, &vmbus_evt); err_setup: - if (IS_ENABLED(CONFIG_PREEMPT_RT) && vmbus_irq_initialized) { + if (IS_ENABLED(CONFIG_PREEMPT_RT)) smpboot_unregister_percpu_thread(&vmbus_irq_threads); - vmbus_irq_initialized = false; - } err_kthread: bus_unregister(&hv_bus); return ret; @@ -3033,10 +3028,9 @@ static void __exit vmbus_exit(void) hv_remove_vmbus_handler(); else free_percpu_irq(vmbus_irq, &vmbus_evt); - if (IS_ENABLED(CONFIG_PREEMPT_RT) && vmbus_irq_initialized) { + if (IS_ENABLED(CONFIG_PREEMPT_RT)) smpboot_unregister_percpu_thread(&vmbus_irq_threads); - vmbus_irq_initialized = false; - } + for_each_online_cpu(cpu) { struct hv_per_cpu_context *hv_cpu = per_cpu_ptr(hv_context.cpu_context, cpu); -- 2.53.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* RE: [PATCH 2/2] hv: vmbus: Remove vmbus_irq_initialized 2026-04-01 15:15 ` [PATCH 2/2] hv: vmbus: Remove vmbus_irq_initialized Sebastian Andrzej Siewior @ 2026-04-04 1:22 ` Michael Kelley 0 siblings, 0 replies; 6+ messages in thread From: Michael Kelley @ 2026-04-04 1:22 UTC (permalink / raw) To: Sebastian Andrzej Siewior, linux-hyperv@vger.kernel.org, linux-rt-devel@lists.linux.dev Cc: K. Y. Srinivasan, Dexuan Cui, Haiyang Zhang, Jan Kiszka, Long Li, Wei Liu From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Sent: Wednesday, April 1, 2026 8:15 AM > > vmbus_irq_initialized is only true if the registration of the per-CPU > threads succeeded. If it failed, the whole registration aborts and the > vmbus_exit() path is never called. > > Remove vmbus_irq_initialized. > > Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Reviewed-by: Michael Kelley <mhklinux@outlook.com> But see comment about the patch Subject prefix from Patch 1 of this series. > --- > drivers/hv/vmbus_drv.c | 14 ++++---------- > 1 file changed, 4 insertions(+), 10 deletions(-) > > diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c > index e44275370ac2a..7417841cd1f70 100644 > --- a/drivers/hv/vmbus_drv.c > +++ b/drivers/hv/vmbus_drv.c > @@ -1392,8 +1392,6 @@ static void run_vmbus_irqd(unsigned int cpu) > __vmbus_isr(); > } > > -static bool vmbus_irq_initialized; > - > static struct smp_hotplug_thread vmbus_irq_threads = { > .store = &vmbus_irqd, > .setup = vmbus_irqd_setup, > @@ -1513,11 +1511,10 @@ static int vmbus_bus_init(void) > * the VMbus interrupt handler. > */ > > - if (IS_ENABLED(CONFIG_PREEMPT_RT) && !vmbus_irq_initialized) { > + if (IS_ENABLED(CONFIG_PREEMPT_RT)) { > ret = smpboot_register_percpu_thread(&vmbus_irq_threads); > if (ret) > goto err_kthread; > - vmbus_irq_initialized = true; > } > > if (vmbus_irq == -1) { > @@ -1561,10 +1558,8 @@ static int vmbus_bus_init(void) > else > free_percpu_irq(vmbus_irq, &vmbus_evt); > err_setup: > - if (IS_ENABLED(CONFIG_PREEMPT_RT) && vmbus_irq_initialized) { > + if (IS_ENABLED(CONFIG_PREEMPT_RT)) > smpboot_unregister_percpu_thread(&vmbus_irq_threads); > - vmbus_irq_initialized = false; > - } > err_kthread: > bus_unregister(&hv_bus); > return ret; > @@ -3033,10 +3028,9 @@ static void __exit vmbus_exit(void) > hv_remove_vmbus_handler(); > else > free_percpu_irq(vmbus_irq, &vmbus_evt); > - if (IS_ENABLED(CONFIG_PREEMPT_RT) && vmbus_irq_initialized) { > + if (IS_ENABLED(CONFIG_PREEMPT_RT)) > smpboot_unregister_percpu_thread(&vmbus_irq_threads); > - vmbus_irq_initialized = false; > - } > + > for_each_online_cpu(cpu) { > struct hv_per_cpu_context *hv_cpu > = per_cpu_ptr(hv_context.cpu_context, cpu); > -- > 2.53.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-07-15 14:33 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-04-01 15:15 [PATCH 0/2] hv: vmbus: Small cleanups Sebastian Andrzej Siewior 2026-04-01 15:15 ` [PATCH 1/2] hv: vmbus: Replace lockdep_hardirq_threaded() with lockdep annotation Sebastian Andrzej Siewior 2026-04-04 1:22 ` Michael Kelley 2026-07-15 14:32 ` Sebastian Andrzej Siewior 2026-04-01 15:15 ` [PATCH 2/2] hv: vmbus: Remove vmbus_irq_initialized Sebastian Andrzej Siewior 2026-04-04 1:22 ` Michael Kelley
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox