Skip to content

Commit 1dba844

Browse files
Koichiro Dengregkh
authored andcommitted
NTB: epf: Avoid calling pci_irq_vector() from hardirq context
commit 4dcddc1 upstream. ntb_epf_vec_isr() calls pci_irq_vector() in hardirq context to derive the vector number. pci_irq_vector() calls msi_get_virq() that takes a mutex and can therefore trigger "scheduling while atomic" splats: BUG: scheduling while atomic: kworker/u33:0/55/0x00010001 ... Call trace: ... schedule+0x38/0x110 schedule_preempt_disabled+0x28/0x50 __mutex_lock.constprop.0+0x848/0x908 __mutex_lock_slowpath+0x18/0x30 mutex_lock+0x4c/0x60 msi_domain_get_virq+0xe8/0x138 pci_irq_vector+0x2c/0x60 ntb_epf_vec_isr+0x28/0x120 [ntb_hw_epf] __handle_irq_event_percpu+0x70/0x3a8 handle_irq_event+0x48/0x100 handle_edge_irq+0x100/0x1c8 ... Cache the Linux IRQ number for vector 0 when vectors are allocated and use it as a base in the ISR. Running the ISR in a threaded IRQ handler would also avoid the problem, but that would be unnecessary here. Fixes: 812ce2f ("NTB: Add support for EPF PCI Non-Transparent Bridge") Signed-off-by: Koichiro Den <den@valinux.co.jp> Signed-off-by: Manivannan Sadhasivam <mani@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Cc: stable@vger.kernel.org # v5.12+ Link: https://patch.msgid.link/20260304083028.1391068-3-den@valinux.co.jp Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 9460468 commit 1dba844

1 file changed

Lines changed: 3 additions & 1 deletion

File tree

drivers/ntb/hw/epf/ntb_hw_epf.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ struct ntb_epf_dev {
9292

9393
int db_val;
9494
u64 db_valid_mask;
95+
int irq_base;
9596
};
9697

9798
#define ntb_ndev(__ntb) container_of(__ntb, struct ntb_epf_dev, ntb)
@@ -318,7 +319,7 @@ static irqreturn_t ntb_epf_vec_isr(int irq, void *dev)
318319
struct ntb_epf_dev *ndev = dev;
319320
int irq_no;
320321

321-
irq_no = irq - pci_irq_vector(ndev->ntb.pdev, 0);
322+
irq_no = irq - ndev->irq_base;
322323
ndev->db_val = irq_no + 1;
323324

324325
if (irq_no == 0)
@@ -350,6 +351,7 @@ static int ntb_epf_init_isr(struct ntb_epf_dev *ndev, int msi_min, int msi_max)
350351
argument &= ~MSIX_ENABLE;
351352
}
352353

354+
ndev->irq_base = pci_irq_vector(pdev, 0);
353355
for (i = 0; i < irq; i++) {
354356
ret = request_irq(pci_irq_vector(pdev, i), ntb_epf_vec_isr,
355357
0, "ntb_epf", ndev);

0 commit comments

Comments
 (0)