From patchwork Mon Jan 20 12:22:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 11342011 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 90FB218B6 for ; Mon, 20 Jan 2020 12:27:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6534E21D7D for ; Mon, 20 Jan 2020 12:27:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727990AbgATM06 (ORCPT ); Mon, 20 Jan 2020 07:26:58 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:9220 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728863AbgATM06 (ORCPT ); Mon, 20 Jan 2020 07:26:58 -0500 Received: from DGGEMS405-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id D057F3807D1B9FD2D331; Mon, 20 Jan 2020 20:26:53 +0800 (CST) Received: from localhost.localdomain (10.69.192.58) by DGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP Server id 14.3.439.0; Mon, 20 Jan 2020 20:26:43 +0800 From: John Garry To: , CC: , , , Xiang Chen , "John Garry" Subject: [PATCH 1/7] scsi: hisi_sas: use threaded irq to process CQ interrupts Date: Mon, 20 Jan 2020 20:22:31 +0800 Message-ID: <1579522957-4393-2-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1579522957-4393-1-git-send-email-john.garry@huawei.com> References: <1579522957-4393-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.58] X-CFilter-Loop: Reflected Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Xiang Chen Currently IRQ_EFFECTIVE_AFF_MASK is enabled for ARM_GIC and ARM_GIC3, so it only allows a single target CPU in the affinity mask to process interrupts and also interrupt thread, and the performance of using threaded irq is almost the same as tasklet. But if the config is not enabled, the interrupt thread will be allowed all the CPUs in the affinity mask. At that situation it promotes much on the performance (about 20%). Note: IRQ_EFFECTIVE_AFF_MASK is configured differently for different architecture chip, and it seems to be better to make it be configured easily. Signed-off-by: Xiang Chen Signed-off-by: John Garry --- drivers/scsi/hisi_sas/hisi_sas.h | 4 ++-- drivers/scsi/hisi_sas/hisi_sas_main.c | 22 +++++++++---------- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 26 +++++++++------------- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 30 ++++++++++++-------------- 4 files changed, 37 insertions(+), 45 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 233c73e01246..838549b19f86 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -181,9 +181,9 @@ struct hisi_sas_port { struct hisi_sas_cq { struct hisi_hba *hisi_hba; const struct cpumask *pci_irq_mask; - struct tasklet_struct tasklet; int rd_point; int id; + int irq_no; }; struct hisi_sas_dq { @@ -627,7 +627,7 @@ extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, extern void hisi_sas_init_mem(struct hisi_hba *hisi_hba); extern void hisi_sas_rst_work_handler(struct work_struct *work); extern void hisi_sas_sync_rst_work_handler(struct work_struct *work); -extern void hisi_sas_kill_tasklets(struct hisi_hba *hisi_hba); +extern void hisi_sas_sync_irqs(struct hisi_hba *hisi_hba); extern void hisi_sas_phy_oob_ready(struct hisi_hba *hisi_hba, int phy_no); extern bool hisi_sas_notify_phy_event(struct hisi_sas_phy *phy, enum hisi_sas_phy_event event); diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 03588ec3c394..c653cce2644a 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1233,10 +1233,10 @@ static int hisi_sas_exec_internal_tmf_task(struct domain_device *device, struct hisi_sas_cq *cq = &hisi_hba->cq[slot->dlvry_queue]; /* - * flush tasklet to avoid free'ing task + * sync irq to avoid free'ing task * before using task in IO completion */ - tasklet_kill(&cq->tasklet); + synchronize_irq(cq->irq_no); slot->task = NULL; } @@ -1626,11 +1626,11 @@ static int hisi_sas_abort_task(struct sas_task *task) if (slot) { /* - * flush tasklet to avoid free'ing task + * sync irq to avoid free'ing task * before using task in IO completion */ cq = &hisi_hba->cq[slot->dlvry_queue]; - tasklet_kill(&cq->tasklet); + synchronize_irq(cq->irq_no); } spin_unlock_irqrestore(&task->task_state_lock, flags); rc = TMF_RESP_FUNC_COMPLETE; @@ -1694,10 +1694,10 @@ static int hisi_sas_abort_task(struct sas_task *task) if (((rc < 0) || (rc == TMF_RESP_FUNC_FAILED)) && task->lldd_task) { /* - * flush tasklet to avoid free'ing task + * sync irq to avoid free'ing task * before using task in IO completion */ - tasklet_kill(&cq->tasklet); + synchronize_irq(cq->irq_no); slot->task = NULL; } } @@ -2076,10 +2076,10 @@ _hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, struct hisi_sas_cq *cq = &hisi_hba->cq[slot->dlvry_queue]; /* - * flush tasklet to avoid free'ing task + * sync irq to avoid free'ing task * before using task in IO completion */ - tasklet_kill(&cq->tasklet); + synchronize_irq(cq->irq_no); slot->task = NULL; } dev_err(dev, "internal task abort: timeout and not done.\n"); @@ -2225,17 +2225,17 @@ void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy) } EXPORT_SYMBOL_GPL(hisi_sas_phy_down); -void hisi_sas_kill_tasklets(struct hisi_hba *hisi_hba) +void hisi_sas_sync_irqs(struct hisi_hba *hisi_hba) { int i; for (i = 0; i < hisi_hba->cq_nvecs; i++) { struct hisi_sas_cq *cq = &hisi_hba->cq[i]; - tasklet_kill(&cq->tasklet); + synchronize_irq(cq->irq_no); } } -EXPORT_SYMBOL_GPL(hisi_sas_kill_tasklets); +EXPORT_SYMBOL_GPL(hisi_sas_sync_irqs); int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type) { diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index 545eaff5f3ee..a0e05a118f2c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -3111,9 +3111,9 @@ static irqreturn_t fatal_axi_int_v2_hw(int irq_no, void *p) return IRQ_HANDLED; } -static void cq_tasklet_v2_hw(unsigned long val) +static irqreturn_t cq_thread_v2_hw(int irq_no, void *p) { - struct hisi_sas_cq *cq = (struct hisi_sas_cq *)val; + struct hisi_sas_cq *cq = p; struct hisi_hba *hisi_hba = cq->hisi_hba; struct hisi_sas_slot *slot; struct hisi_sas_itct *itct; @@ -3181,6 +3181,8 @@ static void cq_tasklet_v2_hw(unsigned long val) /* update rd_point */ cq->rd_point = rd_point; hisi_sas_write32(hisi_hba, COMPL_Q_0_RD_PTR + (0x14 * queue), rd_point); + + return IRQ_HANDLED; } static irqreturn_t cq_interrupt_v2_hw(int irq_no, void *p) @@ -3191,9 +3193,7 @@ static irqreturn_t cq_interrupt_v2_hw(int irq_no, void *p) hisi_sas_write32(hisi_hba, OQ_INT_SRC, 1 << queue); - tasklet_schedule(&cq->tasklet); - - return IRQ_HANDLED; + return IRQ_WAKE_THREAD; } static irqreturn_t sata_int_v2_hw(int irq_no, void *p) @@ -3360,18 +3360,18 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) for (queue_no = 0; queue_no < hisi_hba->queue_count; queue_no++) { struct hisi_sas_cq *cq = &hisi_hba->cq[queue_no]; - struct tasklet_struct *t = &cq->tasklet; - irq = irq_map[queue_no + 96]; - rc = devm_request_irq(dev, irq, cq_interrupt_v2_hw, 0, - DRV_NAME " cq", cq); + cq->irq_no = irq_map[queue_no + 96]; + rc = devm_request_threaded_irq(dev, cq->irq_no, + cq_interrupt_v2_hw, + cq_thread_v2_hw, IRQF_ONESHOT, + DRV_NAME " cq", cq); if (rc) { dev_err(dev, "irq init: could not request cq interrupt %d, rc=%d\n", irq, rc); rc = -ENOENT; goto err_out; } - tasklet_init(t, cq_tasklet_v2_hw, (unsigned long)cq); } hisi_hba->cq_nvecs = hisi_hba->queue_count; @@ -3432,7 +3432,6 @@ static int soft_reset_v2_hw(struct hisi_hba *hisi_hba) interrupt_disable_v2_hw(hisi_hba); hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0x0); - hisi_sas_kill_tasklets(hisi_hba); hisi_sas_stop_phys(hisi_hba); @@ -3606,11 +3605,6 @@ static int hisi_sas_v2_probe(struct platform_device *pdev) static int hisi_sas_v2_remove(struct platform_device *pdev) { - struct sas_ha_struct *sha = platform_get_drvdata(pdev); - struct hisi_hba *hisi_hba = sha->lldd_ha; - - hisi_sas_kill_tasklets(hisi_hba); - return hisi_sas_remove(pdev); } diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index fa05e612d85a..34a3781a2a85 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -2299,9 +2299,9 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) return sts; } -static void cq_tasklet_v3_hw(unsigned long val) +static irqreturn_t cq_thread_v3_hw(int irq_no, void *p) { - struct hisi_sas_cq *cq = (struct hisi_sas_cq *)val; + struct hisi_sas_cq *cq = p; struct hisi_hba *hisi_hba = cq->hisi_hba; struct hisi_sas_slot *slot; struct hisi_sas_complete_v3_hdr *complete_queue; @@ -2338,6 +2338,8 @@ static void cq_tasklet_v3_hw(unsigned long val) /* update rd_point */ cq->rd_point = rd_point; hisi_sas_write32(hisi_hba, COMPL_Q_0_RD_PTR + (0x14 * queue), rd_point); + + return IRQ_HANDLED; } static irqreturn_t cq_interrupt_v3_hw(int irq_no, void *p) @@ -2348,9 +2350,7 @@ static irqreturn_t cq_interrupt_v3_hw(int irq_no, void *p) hisi_sas_write32(hisi_hba, OQ_INT_SRC, 1 << queue); - tasklet_schedule(&cq->tasklet); - - return IRQ_HANDLED; + return IRQ_WAKE_THREAD; } static void setup_reply_map_v3_hw(struct hisi_hba *hisi_hba, int nvecs) @@ -2441,15 +2441,17 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) goto free_irq_vectors; } - /* Init tasklets for cq only */ for (i = 0; i < hisi_hba->cq_nvecs; i++) { struct hisi_sas_cq *cq = &hisi_hba->cq[i]; - struct tasklet_struct *t = &cq->tasklet; int nr = hisi_sas_intr_conv ? 16 : 16 + i; - unsigned long irqflags = hisi_sas_intr_conv ? IRQF_SHARED : 0; - - rc = devm_request_irq(dev, pci_irq_vector(pdev, nr), - cq_interrupt_v3_hw, irqflags, + unsigned long irqflags = hisi_sas_intr_conv ? IRQF_SHARED : + IRQF_ONESHOT; + + cq->irq_no = pci_irq_vector(pdev, nr); + rc = devm_request_threaded_irq(dev, cq->irq_no, + cq_interrupt_v3_hw, + cq_thread_v3_hw, + irqflags, DRV_NAME " cq", cq); if (rc) { dev_err(dev, "could not request cq%d interrupt, rc=%d\n", @@ -2457,8 +2459,6 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) rc = -ENOENT; goto free_irq_vectors; } - - tasklet_init(t, cq_tasklet_v3_hw, (unsigned long)cq); } return 0; @@ -2534,7 +2534,6 @@ static int disable_host_v3_hw(struct hisi_hba *hisi_hba) interrupt_disable_v3_hw(hisi_hba); hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0x0); - hisi_sas_kill_tasklets(hisi_hba); hisi_sas_stop_phys(hisi_hba); @@ -2910,7 +2909,7 @@ static void debugfs_snapshot_prepare_v3_hw(struct hisi_hba *hisi_hba) wait_cmds_complete_timeout_v3_hw(hisi_hba, 100, 5000); - hisi_sas_kill_tasklets(hisi_hba); + hisi_sas_sync_irqs(hisi_hba); } static void debugfs_snapshot_restore_v3_hw(struct hisi_hba *hisi_hba) @@ -3312,7 +3311,6 @@ static void hisi_sas_v3_remove(struct pci_dev *pdev) sas_remove_host(sha->core.shost); hisi_sas_v3_destroy_irqs(pdev, hisi_hba); - hisi_sas_kill_tasklets(hisi_hba); pci_release_regions(pdev); pci_disable_device(pdev); hisi_sas_free(hisi_hba); From patchwork Mon Jan 20 12:22:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 11342009 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D9A14184C for ; Mon, 20 Jan 2020 12:27:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B6AD821D7D for ; Mon, 20 Jan 2020 12:27:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729064AbgATM07 (ORCPT ); Mon, 20 Jan 2020 07:26:59 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:9218 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728913AbgATM06 (ORCPT ); Mon, 20 Jan 2020 07:26:58 -0500 Received: from DGGEMS405-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id C2DEA15C7F90CA827964; Mon, 20 Jan 2020 20:26:53 +0800 (CST) Received: from localhost.localdomain (10.69.192.58) by DGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP Server id 14.3.439.0; Mon, 20 Jan 2020 20:26:44 +0800 From: John Garry To: , CC: , , , Xiang Chen , "John Garry" Subject: [PATCH 2/7] scsi: hisi_sas: replace spin_lock_irqsave/spin_unlock_restore with spin_lock/spin_unlock Date: Mon, 20 Jan 2020 20:22:32 +0800 Message-ID: <1579522957-4393-3-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1579522957-4393-1-git-send-email-john.garry@huawei.com> References: <1579522957-4393-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.58] X-CFilter-Loop: Reflected Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Xiang Chen After changed tasklet to workqueue or threaded irq, some critical resources are only used on threads (not in interrupt or bottom half of interrupt), so replace spin_lock_irqsave/spin_unlock_restore with spin_lock/spin_unlock to protect those critical resources. Signed-off-by: Xiang Chen Signed-off-by: John Garry --- drivers/scsi/hisi_sas/hisi_sas_main.c | 48 +++++++++++--------------- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 12 +++---- 2 files changed, 26 insertions(+), 34 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index c653cce2644a..3e103e86e964 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -163,13 +163,11 @@ static void hisi_sas_slot_index_clear(struct hisi_hba *hisi_hba, int slot_idx) static void hisi_sas_slot_index_free(struct hisi_hba *hisi_hba, int slot_idx) { - unsigned long flags; - if (hisi_hba->hw->slot_index_alloc || slot_idx >= HISI_SAS_UNRESERVED_IPTT) { - spin_lock_irqsave(&hisi_hba->lock, flags); + spin_lock(&hisi_hba->lock); hisi_sas_slot_index_clear(hisi_hba, slot_idx); - spin_unlock_irqrestore(&hisi_hba->lock, flags); + spin_unlock(&hisi_hba->lock); } } @@ -185,12 +183,11 @@ static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba, { int index; void *bitmap = hisi_hba->slot_index_tags; - unsigned long flags; if (scsi_cmnd) return scsi_cmnd->request->tag; - spin_lock_irqsave(&hisi_hba->lock, flags); + spin_lock(&hisi_hba->lock); index = find_next_zero_bit(bitmap, hisi_hba->slot_index_count, hisi_hba->last_slot_index + 1); if (index >= hisi_hba->slot_index_count) { @@ -198,13 +195,13 @@ static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba, hisi_hba->slot_index_count, HISI_SAS_UNRESERVED_IPTT); if (index >= hisi_hba->slot_index_count) { - spin_unlock_irqrestore(&hisi_hba->lock, flags); + spin_unlock(&hisi_hba->lock); return -SAS_QUEUE_FULL; } } hisi_sas_slot_index_set(hisi_hba, index); hisi_hba->last_slot_index = index; - spin_unlock_irqrestore(&hisi_hba->lock, flags); + spin_unlock(&hisi_hba->lock); return index; } @@ -220,7 +217,6 @@ static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba) void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task, struct hisi_sas_slot *slot) { - unsigned long flags; int device_id = slot->device_id; struct hisi_sas_device *sas_dev = &hisi_hba->devices[device_id]; @@ -247,9 +243,9 @@ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task, } } - spin_lock_irqsave(&sas_dev->lock, flags); + spin_lock(&sas_dev->lock); list_del_init(&slot->entry); - spin_unlock_irqrestore(&sas_dev->lock, flags); + spin_unlock(&sas_dev->lock); memset(slot, 0, offsetof(struct hisi_sas_slot, buf)); @@ -489,14 +485,14 @@ static int hisi_sas_task_prep(struct sas_task *task, slot_idx = rc; slot = &hisi_hba->slot_info[slot_idx]; - spin_lock_irqsave(&dq->lock, flags); + spin_lock(&dq->lock); wr_q_index = dq->wr_point; dq->wr_point = (dq->wr_point + 1) % HISI_SAS_QUEUE_SLOTS; list_add_tail(&slot->delivery, &dq->list); - spin_unlock_irqrestore(&dq->lock, flags); - spin_lock_irqsave(&sas_dev->lock, flags); + spin_unlock(&dq->lock); + spin_lock(&sas_dev->lock); list_add_tail(&slot->entry, &sas_dev->list); - spin_unlock_irqrestore(&sas_dev->lock, flags); + spin_unlock(&sas_dev->lock); dlvry_queue = dq->id; dlvry_queue_slot = wr_q_index; @@ -562,7 +558,6 @@ static int hisi_sas_task_exec(struct sas_task *task, gfp_t gfp_flags, { u32 rc; u32 pass = 0; - unsigned long flags; struct hisi_hba *hisi_hba; struct device *dev; struct domain_device *device = task->dev; @@ -606,9 +601,9 @@ static int hisi_sas_task_exec(struct sas_task *task, gfp_t gfp_flags, dev_err(dev, "task exec: failed[%d]!\n", rc); if (likely(pass)) { - spin_lock_irqsave(&dq->lock, flags); + spin_lock(&dq->lock); hisi_hba->hw->start_delivery(dq); - spin_unlock_irqrestore(&dq->lock, flags); + spin_unlock(&dq->lock); } return rc; @@ -659,12 +654,11 @@ static struct hisi_sas_device *hisi_sas_alloc_dev(struct domain_device *device) { struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); struct hisi_sas_device *sas_dev = NULL; - unsigned long flags; int last = hisi_hba->last_dev_id; int first = (hisi_hba->last_dev_id + 1) % HISI_SAS_MAX_DEVICES; int i; - spin_lock_irqsave(&hisi_hba->lock, flags); + spin_lock(&hisi_hba->lock); for (i = first; i != last; i %= HISI_SAS_MAX_DEVICES) { if (hisi_hba->devices[i].dev_type == SAS_PHY_UNUSED) { int queue = i % hisi_hba->queue_count; @@ -684,7 +678,7 @@ static struct hisi_sas_device *hisi_sas_alloc_dev(struct domain_device *device) i++; } hisi_hba->last_dev_id = i; - spin_unlock_irqrestore(&hisi_hba->lock, flags); + spin_unlock(&hisi_hba->lock); return sas_dev; } @@ -1965,14 +1959,14 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id, slot_idx = rc; slot = &hisi_hba->slot_info[slot_idx]; - spin_lock_irqsave(&dq->lock, flags); + spin_lock(&dq->lock); wr_q_index = dq->wr_point; dq->wr_point = (dq->wr_point + 1) % HISI_SAS_QUEUE_SLOTS; list_add_tail(&slot->delivery, &dq->list); - spin_unlock_irqrestore(&dq->lock, flags); - spin_lock_irqsave(&sas_dev->lock, flags); + spin_unlock(&dq->lock); + spin_lock(&sas_dev->lock); list_add_tail(&slot->entry, &sas_dev->list); - spin_unlock_irqrestore(&sas_dev->lock, flags); + spin_unlock(&sas_dev->lock); dlvry_queue = dq->id; dlvry_queue_slot = wr_q_index; @@ -2001,9 +1995,9 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id, spin_unlock_irqrestore(&task->task_state_lock, flags); WRITE_ONCE(slot->ready, 1); /* send abort command to the chip */ - spin_lock_irqsave(&dq->lock, flags); + spin_lock(&dq->lock); hisi_hba->hw->start_delivery(dq); - spin_unlock_irqrestore(&dq->lock, flags); + spin_unlock(&dq->lock); return 0; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index a0e05a118f2c..e05faf315dcd 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -773,7 +773,6 @@ slot_index_alloc_quirk_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_device *sas_dev = device->lldd_dev; int sata_idx = sas_dev->sata_idx; int start, end; - unsigned long flags; if (!sata_dev) { /* @@ -797,12 +796,12 @@ slot_index_alloc_quirk_v2_hw(struct hisi_hba *hisi_hba, end = 64 * (sata_idx + 2); } - spin_lock_irqsave(&hisi_hba->lock, flags); + spin_lock(&hisi_hba->lock); while (1) { start = find_next_zero_bit(bitmap, hisi_hba->slot_index_count, start); if (start >= end) { - spin_unlock_irqrestore(&hisi_hba->lock, flags); + spin_unlock(&hisi_hba->lock); return -SAS_QUEUE_FULL; } /* @@ -814,7 +813,7 @@ slot_index_alloc_quirk_v2_hw(struct hisi_hba *hisi_hba, } set_bit(start, bitmap); - spin_unlock_irqrestore(&hisi_hba->lock, flags); + spin_unlock(&hisi_hba->lock); return start; } @@ -843,9 +842,8 @@ hisi_sas_device *alloc_dev_quirk_v2_hw(struct domain_device *device) struct hisi_sas_device *sas_dev = NULL; int i, sata_dev = dev_is_sata(device); int sata_idx = -1; - unsigned long flags; - spin_lock_irqsave(&hisi_hba->lock, flags); + spin_lock(&hisi_hba->lock); if (sata_dev) if (!sata_index_alloc_v2_hw(hisi_hba, &sata_idx)) @@ -876,7 +874,7 @@ hisi_sas_device *alloc_dev_quirk_v2_hw(struct domain_device *device) } out: - spin_unlock_irqrestore(&hisi_hba->lock, flags); + spin_unlock(&hisi_hba->lock); return sas_dev; } From patchwork Mon Jan 20 12:22:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 11342017 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A67AE159A for ; Mon, 20 Jan 2020 12:27:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8AA8E21D7E for ; Mon, 20 Jan 2020 12:27:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728831AbgATM04 (ORCPT ); Mon, 20 Jan 2020 07:26:56 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:9215 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727011AbgATM04 (ORCPT ); Mon, 20 Jan 2020 07:26:56 -0500 Received: from DGGEMS405-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id BE73EDACE6526C636755; Mon, 20 Jan 2020 20:26:53 +0800 (CST) Received: from localhost.localdomain (10.69.192.58) by DGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP Server id 14.3.439.0; Mon, 20 Jan 2020 20:26:44 +0800 From: John Garry To: , CC: , , , Luo Jiaxing , "John Garry" Subject: [PATCH 3/7] scsi: hisi_sas: Replace magic number when handle channel interrupt Date: Mon, 20 Jan 2020 20:22:33 +0800 Message-ID: <1579522957-4393-4-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1579522957-4393-1-git-send-email-john.garry@huawei.com> References: <1579522957-4393-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.58] X-CFilter-Loop: Reflected Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Luo Jiaxing We use magic number as offset and mask when handle channel interrupt, so use marco to replace it. Signed-off-by: Luo Jiaxing Signed-off-by: John Garry --- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 17 ++++++++++++----- 1 file changed, 12 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 34a3781a2a85..878530f6945f 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -495,6 +495,13 @@ struct hisi_sas_err_record_v3 { #define BASE_VECTORS_V3_HW 16 #define MIN_AFFINE_VECTORS_V3_HW (BASE_VECTORS_V3_HW + 1) +#define CHNL_INT_STS_MSK 0xeeeeeeee +#define CHNL_INT_STS_PHY_MSK 0xe +#define CHNL_INT_STS_INT0_MSK BIT(1) +#define CHNL_INT_STS_INT1_MSK BIT(2) +#define CHNL_INT_STS_INT2_MSK BIT(3) +#define CHNL_WIDTH 4 + enum { DSM_FUNC_ERR_HANDLE_MSI = 0, }; @@ -1819,19 +1826,19 @@ static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p) int phy_no = 0; irq_msk = hisi_sas_read32(hisi_hba, CHNL_INT_STATUS) - & 0xeeeeeeee; + & CHNL_INT_STS_MSK; while (irq_msk) { - if (irq_msk & (2 << (phy_no * 4))) + if (irq_msk & (CHNL_INT_STS_INT0_MSK << (phy_no * CHNL_WIDTH))) handle_chl_int0_v3_hw(hisi_hba, phy_no); - if (irq_msk & (4 << (phy_no * 4))) + if (irq_msk & (CHNL_INT_STS_INT1_MSK << (phy_no * CHNL_WIDTH))) handle_chl_int1_v3_hw(hisi_hba, phy_no); - if (irq_msk & (8 << (phy_no * 4))) + if (irq_msk & (CHNL_INT_STS_INT2_MSK << (phy_no * CHNL_WIDTH))) handle_chl_int2_v3_hw(hisi_hba, phy_no); - irq_msk &= ~(0xe << (phy_no * 4)); + irq_msk &= ~(CHNL_INT_STS_PHY_MSK << (phy_no * CHNL_WIDTH)); phy_no++; } From patchwork Mon Jan 20 12:22:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 11342021 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2F95A184C for ; Mon, 20 Jan 2020 12:27:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1812F22464 for ; Mon, 20 Jan 2020 12:27:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728783AbgATM04 (ORCPT ); Mon, 20 Jan 2020 07:26:56 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:9217 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726796AbgATM04 (ORCPT ); Mon, 20 Jan 2020 07:26:56 -0500 Received: from DGGEMS405-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id CC23A55811EA30424DD9; Mon, 20 Jan 2020 20:26:53 +0800 (CST) Received: from localhost.localdomain (10.69.192.58) by DGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP Server id 14.3.439.0; Mon, 20 Jan 2020 20:26:44 +0800 From: John Garry To: , CC: , , , Luo Jiaxing , "John Garry" Subject: [PATCH 4/7] scsi: hisi_sas: Modify the file permissions of trigger_dump to write only Date: Mon, 20 Jan 2020 20:22:34 +0800 Message-ID: <1579522957-4393-5-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1579522957-4393-1-git-send-email-john.garry@huawei.com> References: <1579522957-4393-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.58] X-CFilter-Loop: Reflected Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Luo Jiaxing The trigger_dump file is only used to manually trigger the dump, and did not provide a read callback function for it, so it's file permission setting to 600 is wrong, and should be changed to 200. Signed-off-by: Luo Jiaxing Signed-off-by: John Garry --- drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 3e103e86e964..61db3376b1f9 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -3930,7 +3930,7 @@ void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev), hisi_sas_debugfs_dir); - debugfs_create_file("trigger_dump", 0600, + debugfs_create_file("trigger_dump", 0200, hisi_hba->debugfs_dir, hisi_hba, &hisi_sas_debugfs_trigger_dump_fops); From patchwork Mon Jan 20 12:22:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 11342029 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 734FC159A for ; Mon, 20 Jan 2020 12:27:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5B82C21D7D for ; Mon, 20 Jan 2020 12:27:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727691AbgATM04 (ORCPT ); Mon, 20 Jan 2020 07:26:56 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:9214 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726889AbgATM04 (ORCPT ); Mon, 20 Jan 2020 07:26:56 -0500 Received: from DGGEMS405-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id C82012768E8DBACB627B; Mon, 20 Jan 2020 20:26:53 +0800 (CST) Received: from localhost.localdomain (10.69.192.58) by DGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP Server id 14.3.439.0; Mon, 20 Jan 2020 20:26:45 +0800 From: John Garry To: , CC: , , , Luo Jiaxing , "John Garry" Subject: [PATCH 5/7] scsi: hisi_sas: Add prints for v3 hw interrupt converge and automatic affinity Date: Mon, 20 Jan 2020 20:22:35 +0800 Message-ID: <1579522957-4393-6-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1579522957-4393-1-git-send-email-john.garry@huawei.com> References: <1579522957-4393-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.58] X-CFilter-Loop: Reflected Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Luo Jiaxing Add prints to inform the user of enabled features. Signed-off-by: Luo Jiaxing Signed-off-by: John Garry --- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 878530f6945f..5f6c6f4ea504 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -2396,6 +2396,8 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) .pre_vectors = BASE_VECTORS_V3_HW, }; + dev_info(dev, "Enable MSI auto-affinity\n"); + min_msi = MIN_AFFINE_VECTORS_V3_HW; hisi_hba->reply_map = devm_kcalloc(dev, nr_cpu_ids, @@ -2448,6 +2450,9 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) goto free_irq_vectors; } + if (hisi_sas_intr_conv) + dev_info(dev, "Enable interrupt converge\n"); + for (i = 0; i < hisi_hba->cq_nvecs; i++) { struct hisi_sas_cq *cq = &hisi_hba->cq[i]; int nr = hisi_sas_intr_conv ? 16 : 16 + i; From patchwork Mon Jan 20 12:22:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 11342023 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9F12A159A for ; Mon, 20 Jan 2020 12:27:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 86228217F4 for ; Mon, 20 Jan 2020 12:27:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728741AbgATM1T (ORCPT ); Mon, 20 Jan 2020 07:27:19 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:9216 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727107AbgATM04 (ORCPT ); Mon, 20 Jan 2020 07:26:56 -0500 Received: from DGGEMS405-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id B09B992273281E360AEA; Mon, 20 Jan 2020 20:26:53 +0800 (CST) Received: from localhost.localdomain (10.69.192.58) by DGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP Server id 14.3.439.0; Mon, 20 Jan 2020 20:26:45 +0800 From: John Garry To: , CC: , , , John Garry Subject: [PATCH 6/7] scsi: hisi_sas: Rename hisi_sas_cq.pci_irq_mask Date: Mon, 20 Jan 2020 20:22:36 +0800 Message-ID: <1579522957-4393-7-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1579522957-4393-1-git-send-email-john.garry@huawei.com> References: <1579522957-4393-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.58] X-CFilter-Loop: Reflected Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org In future we will want to use hisi_sas_cq.pci_irq_mask for non-pci interrupt masks, so rename to be more general. Signed-off-by: John Garry --- drivers/scsi/hisi_sas/hisi_sas.h | 2 +- drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 838549b19f86..2bdd64648ef0 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -180,7 +180,7 @@ struct hisi_sas_port { struct hisi_sas_cq { struct hisi_hba *hisi_hba; - const struct cpumask *pci_irq_mask; + const struct cpumask *irq_mask; int rd_point; int id; int irq_no; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 61db3376b1f9..9a6deb21fe4d 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -2125,7 +2125,7 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, case HISI_SAS_INT_ABT_DEV: for (i = 0; i < hisi_hba->cq_nvecs; i++) { struct hisi_sas_cq *cq = &hisi_hba->cq[i]; - const struct cpumask *mask = cq->pci_irq_mask; + const struct cpumask *mask = cq->irq_mask; if (mask && !cpumask_intersects(cpu_online_mask, mask)) continue; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 5f6c6f4ea504..a2debe0c8185 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -2372,7 +2372,7 @@ static void setup_reply_map_v3_hw(struct hisi_hba *hisi_hba, int nvecs) BASE_VECTORS_V3_HW); if (!mask) goto fallback; - cq->pci_irq_mask = mask; + cq->irq_mask = mask; for_each_cpu(cpu, mask) hisi_hba->reply_map[cpu] = queue; } From patchwork Mon Jan 20 12:22:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 11342015 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BAA2E109A for ; Mon, 20 Jan 2020 12:27:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A2C3222314 for ; Mon, 20 Jan 2020 12:27:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728600AbgATM1G (ORCPT ); Mon, 20 Jan 2020 07:27:06 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:9219 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728901AbgATM06 (ORCPT ); Mon, 20 Jan 2020 07:26:58 -0500 Received: from DGGEMS405-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id B989B718139A8316F1D3; Mon, 20 Jan 2020 20:26:53 +0800 (CST) Received: from localhost.localdomain (10.69.192.58) by DGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP Server id 14.3.439.0; Mon, 20 Jan 2020 20:26:45 +0800 From: John Garry To: , CC: , , , John Garry Subject: [PATCH 7/7] scsi: hisi_sas: Use reply map for v2 hw Date: Mon, 20 Jan 2020 20:22:37 +0800 Message-ID: <1579522957-4393-8-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1579522957-4393-1-git-send-email-john.garry@huawei.com> References: <1579522957-4393-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.58] X-CFilter-Loop: Reflected Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org With the aim of boosting performance, switch v2 hw to using reply map, i.e. pseudo blk-mq. This really when we're running a distro with irqbalance running. The reason being that the irqbalance can fiddle with the completion queue affinity, such that we random cpus servicing the CQs. It's not much better without irqbalance, where it is always cpu0. Distro read fio performance for 6x SAS SSDs goes from ~450K IOPS -> 650K IOPS. To continuing support manually setting the irq affinity, introduce module parameter auto_affine_interrupts, which is default off. Signed-off-by: John Garry --- drivers/scsi/hisi_sas/hisi_sas.h | 3 ++ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 54 +++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 2bdd64648ef0..0612fc929a2d 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -385,6 +386,8 @@ struct hisi_hba { spinlock_t lock; struct semaphore sem; + struct irq_affinity_desc affinity_masks[HISI_SAS_MAX_QUEUES]; + struct timer_list timer; struct workqueue_struct *wq; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index e05faf315dcd..533515e85f64 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -417,6 +417,11 @@ struct sig_atten_lu_s { u32 sas_phy_ctrl; }; +static bool auto_affine_interrupts; +module_param(auto_affine_interrupts, bool, 0444); +MODULE_PARM_DESC(auto_affine_interrupts, "Enable auto-affinity of completion queue interrupts:\n" + "default is off"); + static const struct hisi_sas_hw_error one_bit_ecc_errors[] = { { .irq_msk = BIT(SAS_ECC_INTR_DQE_ECC_1B_OFF), @@ -3304,6 +3309,24 @@ static irq_handler_t fatal_interrupts[HISI_SAS_FATAL_INT_NR] = { fatal_axi_int_v2_hw }; +static void setup_reply_map_v2_hw(struct hisi_hba *hisi_hba) +{ + int queue, cpu; + + for (queue = 0; queue < hisi_hba->queue_count; queue++) { + struct hisi_sas_cq *cq = &hisi_hba->cq[queue]; + struct irq_affinity_desc *mask; + struct cpumask *cpumask; + + mask = &hisi_hba->affinity_masks[queue]; + cpumask = &mask->mask; + + cq->irq_mask = cpumask; + for_each_cpu(cpu, cpumask) + hisi_hba->reply_map[cpu] = queue; + } +} + /** * There is a limitation in the hip06 chipset that we need * to map in all mbigen interrupts, even if they are not used. @@ -3315,6 +3338,27 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) int irq, rc = 0, irq_map[128]; int i, phy_no, fatal_no, queue_no; + if (auto_affine_interrupts) { + struct irq_affinity_desc *masks; + struct irq_affinity desc = {}; + int nvec; + + nvec = hisi_hba->queue_count; + masks = irq_create_affinity_masks(nvec, &desc); + if (!masks) + return -ENOMEM; + + memcpy(hisi_hba->affinity_masks, masks, nvec * sizeof(*masks)); + kfree(masks); + + hisi_hba->reply_map = devm_kcalloc(dev, nr_cpu_ids, + sizeof(unsigned int), + GFP_KERNEL); + if (!hisi_hba->reply_map) + return -ENOMEM; + setup_reply_map_v2_hw(hisi_hba); + } + for (i = 0; i < 128; i++) irq_map[i] = platform_get_irq(pdev, i); @@ -3358,11 +3402,16 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) for (queue_no = 0; queue_no < hisi_hba->queue_count; queue_no++) { struct hisi_sas_cq *cq = &hisi_hba->cq[queue_no]; + unsigned long irqflags = IRQF_ONESHOT; + + if (auto_affine_interrupts) + irqflags |= IRQF_NOBALANCING; cq->irq_no = irq_map[queue_no + 96]; + rc = devm_request_threaded_irq(dev, cq->irq_no, cq_interrupt_v2_hw, - cq_thread_v2_hw, IRQF_ONESHOT, + cq_thread_v2_hw, irqflags, DRV_NAME " cq", cq); if (rc) { dev_err(dev, "irq init: could not request cq interrupt %d, rc=%d\n", @@ -3370,6 +3419,9 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) rc = -ENOENT; goto err_out; } + + if (auto_affine_interrupts) + irq_set_affinity(cq->irq_no, cq->irq_mask); } hisi_hba->cq_nvecs = hisi_hba->queue_count;