The wave5 VPU driver uses spin_lock_irqsave() within the interrupt
handler wave5_vpu_handle_irq(), which triggers “sleeping function
called from invalid context” warnings in PREEMPT_RT kernels.
This occurs because the IRQF_ONESHOT flag forces the primary IRQ handler
(wave5_vpu_irq) to execute in hard IRQ context even under PREEMPT_RT.
When the primary handler calls wave5_vpu_handle_irq(), which uses
spinlock, this lock is converted to rt_spinlock that may sleep,
resulting in the warning.
The IRQF_ONESHOT flag is used to keep the interrupt line masked until
the threaded handler completes. Typically, it is employed when there is
only a threaded handler and no primary handler.
In the wave5 VPU driver, prior to commit 587879266fe5 ("FROMLIST: media:
chips-media: wave5: Fix Null reference while testing fluster"), there was
no primary handler, so the use of IRQF_ONESHOT was correct. However,
that commit introduced a primary handler and also cleared the interrupt
status within it. With these changes, the use of IRQF_ONESHOT is
no longer appropriate.
Therefore, removing the IRQF_ONESHOT flag allows the primary handler to
run in threaded interrupt context on PREEMPT_RT kernels. This moves all
rt_spinlock usage to thread context, where sleeping is permitted.
Error log before fix:
BUG: sleeping function called from invalid context at
kernel/locking/spinlock_rt.c:48
in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 0, name: swapper/0
preempt_count: 10001, expected: 0
RCU nest depth: 0, expected: 0
CPU: 0 UID: 0 PID: 0 Comm: swapper/0
Tainted: [W]=WARN, [O]=OOT_MODULE
Hardware name: Texas Instruments J722S EVM (DT)
Call trace:
dump_backtrace.part.0+0xdc/0xf0
show_stack+0x20/0x38
dump_stack_lvl+0x60/0x80
dump_stack+0x18/0x28
__might_resched+0x12c/0x160
rt_spin_lock+0x38/0xc8
wave5_vpu_handle_irq+0xa0/0x288 [wave5]
wave5_vpu_irq+0x4c/0x70 [wave5]
__handle_irq_event_percpu+0x70/0x278
handle_irq_event+0x54/0xd0
handle_fasteoi_irq+0xa8/0x240
handle_irq_desc+0x3c/0x68
generic_handle_domain_irq+0x24/0x40
gic_handle_irq+0x64/0x148
call_on_irq_stack+0x30/0x88
do_interrupt_handler+0x88/0xa0
el1_interrupt+0x34/0x68
el1h_64_irq_handler+0x18/0x28
el1h_64_irq+0x64/0x68
default_idle_call+0x50/0x110
do_idle+0xb8/0xe0
cpu_startup_entry+0x40/0x50
rest_init+0xe0/0xe8
start_kernel+0x6d8/0x6e0
__primary_switched+0x80/0x90
Fixes: 587879266fe5 ("FROMLIST: media: chips-media: wave5: Fix Null reference
while testing fluster")
Suggested-by: Kevin Hao <[email protected]>
Signed-off-by: Xulin Sun <[email protected]>
---
drivers/media/platform/chips-media/wave5/wave5-vpu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu.c
b/drivers/media/platform/chips-media/wave5/wave5-vpu.c
index a348e2e2eae2..970da54d007d 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu.c
@@ -394,7 +394,7 @@ static int wave5_vpu_probe(struct platform_device *pdev)
kthread_init_work(&dev->work, wave5_vpu_irq_work_fn);
} else {
ret = devm_request_threaded_irq(&pdev->dev, dev->irq,
wave5_vpu_irq,
- wave5_vpu_irq_thread,
IRQF_ONESHOT, "vpu_irq", dev);
+ wave5_vpu_irq_thread, 0,
"vpu_irq", dev);
if (ret) {
dev_err(&pdev->dev, "Register interrupt handler, fail:
%d\n", ret);
goto err_enc_unreg;
--
2.34.1
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#16182):
https://lists.yoctoproject.org/g/linux-yocto/message/16182
Mute This Topic: https://lists.yoctoproject.org/mt/117276495/21656
Group Owner: [email protected]
Unsubscribe: https://lists.yoctoproject.org/g/linux-yocto/unsub
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-