Skip to content

Commit 554fb72

Browse files
77liuqimartinkpetersen
authored andcommitted
scsi: hisi_sas: Free irq vectors in order for v3 HW
If the driver probe fails to request the channel IRQ or fatal IRQ, the driver will free the IRQ vectors before freeing the IRQs in free_irq(), and this will cause a kernel BUG like this: ------------[ cut here ]------------ kernel BUG at drivers/pci/msi.c:369! Internal error: Oops - BUG: 0 [#1] PREEMPT SMP Call trace: free_msi_irqs+0x118/0x13c pci_disable_msi+0xfc/0x120 pci_free_irq_vectors+0x24/0x3c hisi_sas_v3_probe+0x360/0x9d0 [hisi_sas_v3_hw] local_pci_probe+0x44/0xb0 work_for_cpu_fn+0x20/0x34 process_one_work+0x1d0/0x340 worker_thread+0x2e0/0x460 kthread+0x180/0x190 ret_from_fork+0x10/0x20 ---[ end trace b88990335b610c11 ]--- So we use devm_add_action() to control the order in which we free the vectors. Link: https://lore.kernel.org/r/1645703489-87194-4-git-send-email-john.garry@huawei.com Signed-off-by: Qi Liu <liuqi115@huawei.com> Signed-off-by: John Garry <john.garry@huawei.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 512623d commit 554fb72

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

drivers/scsi/hisi_sas/hisi_sas_v3_hw.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2397,17 +2397,25 @@ static irqreturn_t cq_interrupt_v3_hw(int irq_no, void *p)
23972397
return IRQ_WAKE_THREAD;
23982398
}
23992399

2400+
static void hisi_sas_v3_free_vectors(void *data)
2401+
{
2402+
struct pci_dev *pdev = data;
2403+
2404+
pci_free_irq_vectors(pdev);
2405+
}
2406+
24002407
static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba)
24012408
{
24022409
int vectors;
24032410
int max_msi = HISI_SAS_MSI_COUNT_V3_HW, min_msi;
24042411
struct Scsi_Host *shost = hisi_hba->shost;
2412+
struct pci_dev *pdev = hisi_hba->pci_dev;
24052413
struct irq_affinity desc = {
24062414
.pre_vectors = BASE_VECTORS_V3_HW,
24072415
};
24082416

24092417
min_msi = MIN_AFFINE_VECTORS_V3_HW;
2410-
vectors = pci_alloc_irq_vectors_affinity(hisi_hba->pci_dev,
2418+
vectors = pci_alloc_irq_vectors_affinity(pdev,
24112419
min_msi, max_msi,
24122420
PCI_IRQ_MSI |
24132421
PCI_IRQ_AFFINITY,
@@ -2419,6 +2427,7 @@ static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba)
24192427
hisi_hba->cq_nvecs = vectors - BASE_VECTORS_V3_HW;
24202428
shost->nr_hw_queues = hisi_hba->cq_nvecs;
24212429

2430+
devm_add_action(&pdev->dev, hisi_sas_v3_free_vectors, pdev);
24222431
return 0;
24232432
}
24242433

@@ -4768,7 +4777,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
47684777

47694778
rc = scsi_add_host(shost, dev);
47704779
if (rc)
4771-
goto err_out_free_irq_vectors;
4780+
goto err_out_debugfs;
47724781

47734782
rc = sas_register_ha(sha);
47744783
if (rc)
@@ -4799,8 +4808,6 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
47994808
sas_unregister_ha(sha);
48004809
err_out_register_ha:
48014810
scsi_remove_host(shost);
4802-
err_out_free_irq_vectors:
4803-
pci_free_irq_vectors(pdev);
48044811
err_out_debugfs:
48054812
debugfs_exit_v3_hw(hisi_hba);
48064813
err_out_ha:
@@ -4824,7 +4831,6 @@ hisi_sas_v3_destroy_irqs(struct pci_dev *pdev, struct hisi_hba *hisi_hba)
48244831

48254832
devm_free_irq(&pdev->dev, pci_irq_vector(pdev, nr), cq);
48264833
}
4827-
pci_free_irq_vectors(pdev);
48284834
}
48294835

48304836
static void hisi_sas_v3_remove(struct pci_dev *pdev)

0 commit comments

Comments
 (0)