mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 16:24:13 +08:00
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>
This commit is contained in:
parent
512623de52
commit
554fb72ee3
@ -2397,17 +2397,25 @@ static irqreturn_t cq_interrupt_v3_hw(int irq_no, void *p)
|
||||
return IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
static void hisi_sas_v3_free_vectors(void *data)
|
||||
{
|
||||
struct pci_dev *pdev = data;
|
||||
|
||||
pci_free_irq_vectors(pdev);
|
||||
}
|
||||
|
||||
static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba)
|
||||
{
|
||||
int vectors;
|
||||
int max_msi = HISI_SAS_MSI_COUNT_V3_HW, min_msi;
|
||||
struct Scsi_Host *shost = hisi_hba->shost;
|
||||
struct pci_dev *pdev = hisi_hba->pci_dev;
|
||||
struct irq_affinity desc = {
|
||||
.pre_vectors = BASE_VECTORS_V3_HW,
|
||||
};
|
||||
|
||||
min_msi = MIN_AFFINE_VECTORS_V3_HW;
|
||||
vectors = pci_alloc_irq_vectors_affinity(hisi_hba->pci_dev,
|
||||
vectors = pci_alloc_irq_vectors_affinity(pdev,
|
||||
min_msi, max_msi,
|
||||
PCI_IRQ_MSI |
|
||||
PCI_IRQ_AFFINITY,
|
||||
@ -2419,6 +2427,7 @@ static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba)
|
||||
hisi_hba->cq_nvecs = vectors - BASE_VECTORS_V3_HW;
|
||||
shost->nr_hw_queues = hisi_hba->cq_nvecs;
|
||||
|
||||
devm_add_action(&pdev->dev, hisi_sas_v3_free_vectors, pdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4768,7 +4777,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
|
||||
rc = scsi_add_host(shost, dev);
|
||||
if (rc)
|
||||
goto err_out_free_irq_vectors;
|
||||
goto err_out_debugfs;
|
||||
|
||||
rc = sas_register_ha(sha);
|
||||
if (rc)
|
||||
@ -4799,8 +4808,6 @@ err_out_hw_init:
|
||||
sas_unregister_ha(sha);
|
||||
err_out_register_ha:
|
||||
scsi_remove_host(shost);
|
||||
err_out_free_irq_vectors:
|
||||
pci_free_irq_vectors(pdev);
|
||||
err_out_debugfs:
|
||||
debugfs_exit_v3_hw(hisi_hba);
|
||||
err_out_ha:
|
||||
@ -4824,7 +4831,6 @@ hisi_sas_v3_destroy_irqs(struct pci_dev *pdev, struct hisi_hba *hisi_hba)
|
||||
|
||||
devm_free_irq(&pdev->dev, pci_irq_vector(pdev, nr), cq);
|
||||
}
|
||||
pci_free_irq_vectors(pdev);
|
||||
}
|
||||
|
||||
static void hisi_sas_v3_remove(struct pci_dev *pdev)
|
||||
|
Loading…
Reference in New Issue
Block a user