]> Gentwo Git Trees - linux/.git/commitdiff
PCI: endpoint: pci-epf-test: Fix sleeping function being called from atomic context
authorBhanu Seshu Kumar Valluri <bhanuseshukumar@gmail.com>
Tue, 14 Oct 2025 02:41:09 +0000 (08:11 +0530)
committerManivannan Sadhasivam <mani@kernel.org>
Sun, 26 Oct 2025 15:50:24 +0000 (21:20 +0530)
When Root Complex (RC) triggers a Doorbell interrupt to Endpoint (EP), it
triggers the below warning in the EP:

 BUG: sleeping function called from invalid context at kernel/locking/mutex.c:271
 Call trace:
  __might_resched+0x130/0x158
  __might_sleep+0x70/0x88
  mutex_lock+0x2c/0x80
  pci_epc_get_msi+0x78/0xd8
  pci_epf_test_raise_irq.isra.0+0x74/0x138
  pci_epf_test_doorbell_handler+0x34/0x50

The BUG arises because the EP's pci_epf_test_doorbell_handler() which is
running in the hard IRQ context is making an indirect call to
pci_epc_get_msi(), which uses mutex inside.

To fix the issue, convert the hard IRQ handler to a threaded IRQ handler to
allow it to call functions that can sleep during bottom half execution.
Also, register the threaded IRQ handler with IRQF_ONESHOT to keep the
interrupt line disabled until the threaded IRQ handler completes execution.

Fixes: eff0c286aa91 ("PCI: endpoint: pci-epf-test: Add doorbell test support")
Signed-off-by: Bhanu Seshu Kumar Valluri <bhanuseshukumar@gmail.com>
[mani: reworded description a bit]
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Reviewed-by: Niklas Cassel <cassel@kernel.org>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20251014024109.42287-1-bhanuseshukumar@gmail.com
drivers/pci/endpoint/functions/pci-epf-test.c

index 31617772ad5165e3d2f156c327a18179f3b8aa07..b05e8db575c35377f12ae47242646d02d97480a3 100644 (file)
@@ -730,8 +730,9 @@ static void pci_epf_test_enable_doorbell(struct pci_epf_test *epf_test,
        if (bar < BAR_0)
                goto err_doorbell_cleanup;
 
-       ret = request_irq(epf->db_msg[0].virq, pci_epf_test_doorbell_handler, 0,
-                         "pci-ep-test-doorbell", epf_test);
+       ret = request_threaded_irq(epf->db_msg[0].virq, NULL,
+                                  pci_epf_test_doorbell_handler, IRQF_ONESHOT,
+                                  "pci-ep-test-doorbell", epf_test);
        if (ret) {
                dev_err(&epf->dev,
                        "Failed to request doorbell IRQ: %d\n",