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]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to