From: Xiang Chen <chenxiang66@xxxxxxxxxxxxx> For when managed interrupts are used (and shost->nr_hw_queues is set), a fixed queue - set per-device - is still used for internal IOs. If all the CPUs mapped to that queue are offlined, then the completions for that queue are not serviced and any internal IOs will timeout. Fix by selecting a queue for internal IOs from the queue mapped from the current CPU in this scenario. This is still not ideal, as it does not deal with CPU hotplug for inflight internal IOs, and needs proper support from [0]. [0] https://lore.kernel.org/linux-scsi/20200703130122.111448-1-hare@xxxxxxx/T/#m7d77d049b18f33a24ef206af69ebb66d07440556 Fixes: 8d98416a55eb ("scsi: hisi_sas: Switch v3 hw to MQ") Signed-off-by: Xiang Chen <chenxiang66@xxxxxxxxxxxxx> Signed-off-by: John Garry <john.garry@xxxxxxxxxx> --- Hi Martin, James, This is based on mkp 5.10/scsi-fixes, and please try to include for v5.10, sorry for the lateness, thanks! diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index c8dd8588f800..274ccf18ce2d 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -452,6 +452,12 @@ static int hisi_sas_task_prep(struct sas_task *task, blk_tag = blk_mq_unique_tag(scmd->request); dq_index = blk_mq_unique_tag_to_hwq(blk_tag); *dq_pointer = dq = &hisi_hba->dq[dq_index]; + } else if (hisi_hba->shost->nr_hw_queues) { + struct Scsi_Host *shost = hisi_hba->shost; + struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; + int queue = qmap->mq_map[raw_smp_processor_id()]; + + *dq_pointer = dq = &hisi_hba->dq[queue]; } else { *dq_pointer = dq = sas_dev->dq; } diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 7133ca859b5e..960de375ce69 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -2452,6 +2452,11 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) rc = -ENOENT; goto free_irq_vectors; } + cq->irq_mask = pci_irq_get_affinity(pdev, i + BASE_VECTORS_V3_HW); + if (!cq->irq_mask) { + dev_err(dev, "could not get cq%d irq affinity!\n", i); + return -ENOENT; + } } return 0; -- 2.26.2