lkml.org 
[lkml]   [2022]   [Feb]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 3/6] scsi: hisi_sas: Free irq vectors in order for v3 HW
Date
From: Qi Liu <liuqi115@huawei.com>

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.

Signed-off-by: Qi Liu <liuqi115@huawei.com>
Signed-off-by: John Garry <john.garry@huawei.com>
---
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index 29a566a19219..5b5557cab7ed 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -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 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
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)
--
2.26.2
\
 
 \ /
  Last update: 2022-02-24 12:58    [W:0.121 / U:0.400 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site