From patchwork Wed May 9 15:10:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 135294 Delivered-To: patch@linaro.org Received: by 10.46.151.6 with SMTP id r6csp5760876lji; Wed, 9 May 2018 08:12:53 -0700 (PDT) X-Google-Smtp-Source: AB8JxZq0WmVvuxsfgBMOgY4f4oZipW2KqAEia3uZ431R4OkRc6ZgQKeqm1e/o/ow9WVa6PHMklop X-Received: by 2002:a17:902:c81:: with SMTP id 1-v6mr45226799plt.126.1525878773140; Wed, 09 May 2018 08:12:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525878773; cv=none; d=google.com; s=arc-20160816; b=LzfHFTPZuL2vUxM3+ZTTp+DVIt0O3ocnXjZKtfuFdJoMvx6IVq8zOHLAIT+LPXUblA M+3M2w5pMcgfGSGnq622eOFsEQ437Qy+KHK5OThe+frno7QfpceqyJjJFAnTLSQO9mSO 9gk/bn0ebeVSrTYddPNaN4zu/UY34fH/gsP85byFcu9eRRNTePoQDMDFAvmQCYkpabD7 lBb9gDlpS59JA0DvVbm2FC4TTdrDizXzRSz3/7T20DbZFJyjxzTG2rWKZqJoV1MqB8UH bR0hjzYOtGgZYucXe2ATpLVGBLHWYa7Vcnla5Xx9jUKDotCfUNV9qOP7gp3TLbF8WGrv Y+og== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:arc-authentication-results; bh=OaWBKzu5x5Yu973Ch6OpJGLO8a0T8sAFHtubYNAu5AI=; b=Ajfc+1osfEScttCpA7qfeup8E6X2TY13zrRvCjVDNJ88mtC3nQ4MzDw1AZlZ0aLiXX Y8g1wTCaQoF6G5EiLo0+4Rvlp/TOaryuoDJ4d2kK/F255MFSYQWQlmMh58OS6WDFm2i1 kIEbhw9a9KjqoJuzIcnthN+GsVZsQyFjnjUrhPDPbPZtkkL5cjwA9baDCo8ICqh+jSvt o0De6XA9W+k8rMi6XNwgkGL75BT58CfTMYYpknmaCO1wkqFoKCNo+pjT/GvEOudF+rSW SE8YG5YWMvog/ZZHEsiP1TRLFc1OOA6+UYur3CllJNK8nNoQJrvbWVkTJt42dEcZNEtx p21A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u17-v6si6910738pge.240.2018.05.09.08.12.52; Wed, 09 May 2018 08:12:53 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964910AbeEIPMp (ORCPT + 29 others); Wed, 9 May 2018 11:12:45 -0400 Received: from szxga06-in.huawei.com ([45.249.212.32]:47137 "EHLO huawei.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S964843AbeEIPMQ (ORCPT ); Wed, 9 May 2018 11:12:16 -0400 Received: from DGGEMS410-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 6CE6893C41965; Wed, 9 May 2018 23:12:08 +0800 (CST) Received: from localhost.localdomain (10.67.212.75) by DGGEMS410-HUB.china.huawei.com (10.3.19.210) with Microsoft SMTP Server id 14.3.361.1; Wed, 9 May 2018 23:11:59 +0800 From: John Garry To: , CC: , , , Xiang Chen , "John Garry" Subject: [PATCH 1/6] scsi: hisi_sas: relocate smp sg map Date: Wed, 9 May 2018 23:10:45 +0800 Message-ID: <1525878650-213087-2-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1525878650-213087-1-git-send-email-john.garry@huawei.com> References: <1525878650-213087-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.212.75] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Xiang Chen Currently we use DQ lock to protect delivery of DQ entry one by one. To optimise to allow more than one slot to be built for a single DQ in parallel, we need to remove the DQ lock when preparing slots, prior to delivery. To achieve this, we rearrange the slot build order to ensure that once we allocate a slot for a task, we do cannot fail to deliver the task. In this patch, we rearrange the slot building for SMP tasks to ensure that sg mapping part (which can fail) happens before we allocate the slot in the DQ. Signed-off-by: Xiang Chen Signed-off-by: John Garry --- drivers/scsi/hisi_sas/hisi_sas_main.c | 56 ++++++++++++++++++++++++++-------- drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 33 ++------------------ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 35 ++------------------- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 33 ++------------------ 4 files changed, 51 insertions(+), 106 deletions(-) -- 1.9.1 diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index ff5b8d7..0ce7c71 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -319,7 +319,8 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq struct hisi_sas_cmd_hdr *cmd_hdr_base; struct asd_sas_port *sas_port = device->port; struct device *dev = hisi_hba->dev; - int dlvry_queue_slot, dlvry_queue, n_elem = 0, rc, slot_idx; + int dlvry_queue_slot, dlvry_queue, rc, slot_idx; + int n_elem = 0, n_elem_req = 0, n_elem_resp = 0; unsigned long flags; if (!sas_port) { @@ -358,6 +359,8 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq } if (!sas_protocol_ata(task->task_proto)) { + unsigned int req_len, resp_len; + if (task->num_scatter) { n_elem = dma_map_sg(dev, task->scatter, task->num_scatter, task->data_dir); @@ -365,6 +368,29 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq rc = -ENOMEM; goto prep_out; } + } else if (task->task_proto & SAS_PROTOCOL_SMP) { + n_elem_req = dma_map_sg(dev, &task->smp_task.smp_req, + 1, DMA_TO_DEVICE); + if (!n_elem_req) { + rc = -ENOMEM; + goto prep_out; + } + req_len = sg_dma_len(&task->smp_task.smp_req); + if (req_len & 0x3) { + rc = -EINVAL; + goto err_out_dma_unmap; + } + n_elem_resp = dma_map_sg(dev, &task->smp_task.smp_resp, + 1, DMA_FROM_DEVICE); + if (!n_elem_req) { + rc = -ENOMEM; + goto err_out_dma_unmap; + } + resp_len = sg_dma_len(&task->smp_task.smp_resp); + if (resp_len & 0x3) { + rc = -EINVAL; + goto err_out_dma_unmap; + } } } else n_elem = task->num_scatter; @@ -375,11 +401,9 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq device); else rc = hisi_sas_slot_index_alloc(hisi_hba, &slot_idx); - if (rc) { - spin_unlock_irqrestore(&hisi_hba->lock, flags); - goto err_out; - } spin_unlock_irqrestore(&hisi_hba->lock, flags); + if (rc) + goto err_out_dma_unmap; rc = hisi_hba->hw->get_free_slot(hisi_hba, dq); if (rc) @@ -458,14 +482,22 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq spin_lock_irqsave(&hisi_hba->lock, flags); hisi_sas_slot_index_free(hisi_hba, slot_idx); spin_unlock_irqrestore(&hisi_hba->lock, flags); -err_out: - dev_err(dev, "task prep: failed[%d]!\n", rc); - if (!sas_protocol_ata(task->task_proto)) - if (n_elem) - dma_unmap_sg(dev, task->scatter, - task->num_scatter, - task->data_dir); +err_out_dma_unmap: + if (!sas_protocol_ata(task->task_proto)) { + if (task->num_scatter) { + dma_unmap_sg(dev, task->scatter, task->num_scatter, + task->data_dir); + } else if (task->task_proto & SAS_PROTOCOL_SMP) { + if (n_elem_req) + dma_unmap_sg(dev, &task->smp_task.smp_req, + 1, DMA_TO_DEVICE); + if (n_elem_resp) + dma_unmap_sg(dev, &task->smp_task.smp_resp, + 1, DMA_FROM_DEVICE); + } + } prep_out: + dev_err(dev, "task prep: failed[%d]!\n", rc); return rc; } diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 84a0ccc..3769d70 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -974,38 +974,17 @@ static int prep_smp_v1_hw(struct hisi_hba *hisi_hba, struct sas_task *task = slot->task; struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr; struct domain_device *device = task->dev; - struct device *dev = hisi_hba->dev; struct hisi_sas_port *port = slot->port; - struct scatterlist *sg_req, *sg_resp; + struct scatterlist *sg_req; struct hisi_sas_device *sas_dev = device->lldd_dev; dma_addr_t req_dma_addr; - unsigned int req_len, resp_len; - int elem, rc; + unsigned int req_len; - /* - * DMA-map SMP request, response buffers - */ /* req */ sg_req = &task->smp_task.smp_req; - elem = dma_map_sg(dev, sg_req, 1, DMA_TO_DEVICE); - if (!elem) - return -ENOMEM; req_len = sg_dma_len(sg_req); req_dma_addr = sg_dma_address(sg_req); - /* resp */ - sg_resp = &task->smp_task.smp_resp; - elem = dma_map_sg(dev, sg_resp, 1, DMA_FROM_DEVICE); - if (!elem) { - rc = -ENOMEM; - goto err_out_req; - } - resp_len = sg_dma_len(sg_resp); - if ((req_len & 0x3) || (resp_len & 0x3)) { - rc = -EINVAL; - goto err_out_resp; - } - /* create header */ /* dw0 */ hdr->dw0 = cpu_to_le32((port->id << CMD_HDR_PORT_OFF) | @@ -1027,14 +1006,6 @@ static int prep_smp_v1_hw(struct hisi_hba *hisi_hba, hdr->sts_buffer_addr = cpu_to_le64(hisi_sas_status_buf_addr_dma(slot)); return 0; - -err_out_resp: - dma_unmap_sg(dev, &slot->task->smp_task.smp_resp, 1, - DMA_FROM_DEVICE); -err_out_req: - dma_unmap_sg(dev, &slot->task->smp_task.smp_req, 1, - DMA_TO_DEVICE); - return rc; } static int prep_ssp_v1_hw(struct hisi_hba *hisi_hba, diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index 9e68731..ac0a0b2 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -1721,37 +1721,16 @@ static int prep_smp_v2_hw(struct hisi_hba *hisi_hba, struct sas_task *task = slot->task; struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr; struct domain_device *device = task->dev; - struct device *dev = hisi_hba->dev; struct hisi_sas_port *port = slot->port; - struct scatterlist *sg_req, *sg_resp; + struct scatterlist *sg_req; struct hisi_sas_device *sas_dev = device->lldd_dev; dma_addr_t req_dma_addr; - unsigned int req_len, resp_len; - int elem, rc; + unsigned int req_len; - /* - * DMA-map SMP request, response buffers - */ /* req */ sg_req = &task->smp_task.smp_req; - elem = dma_map_sg(dev, sg_req, 1, DMA_TO_DEVICE); - if (!elem) - return -ENOMEM; - req_len = sg_dma_len(sg_req); req_dma_addr = sg_dma_address(sg_req); - - /* resp */ - sg_resp = &task->smp_task.smp_resp; - elem = dma_map_sg(dev, sg_resp, 1, DMA_FROM_DEVICE); - if (!elem) { - rc = -ENOMEM; - goto err_out_req; - } - resp_len = sg_dma_len(sg_resp); - if ((req_len & 0x3) || (resp_len & 0x3)) { - rc = -EINVAL; - goto err_out_resp; - } + req_len = sg_dma_len(&task->smp_task.smp_req); /* create header */ /* dw0 */ @@ -1775,14 +1754,6 @@ static int prep_smp_v2_hw(struct hisi_hba *hisi_hba, hdr->sts_buffer_addr = cpu_to_le64(hisi_sas_status_buf_addr_dma(slot)); return 0; - -err_out_resp: - dma_unmap_sg(dev, &slot->task->smp_task.smp_resp, 1, - DMA_FROM_DEVICE); -err_out_req: - dma_unmap_sg(dev, &slot->task->smp_task.smp_req, 1, - DMA_TO_DEVICE); - return rc; } static int prep_ssp_v2_hw(struct hisi_hba *hisi_hba, diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 492c3be..cea5354 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -986,38 +986,17 @@ static int prep_smp_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task = slot->task; struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr; struct domain_device *device = task->dev; - struct device *dev = hisi_hba->dev; struct hisi_sas_port *port = slot->port; - struct scatterlist *sg_req, *sg_resp; + struct scatterlist *sg_req; struct hisi_sas_device *sas_dev = device->lldd_dev; dma_addr_t req_dma_addr; - unsigned int req_len, resp_len; - int elem, rc; + unsigned int req_len; - /* - * DMA-map SMP request, response buffers - */ /* req */ sg_req = &task->smp_task.smp_req; - elem = dma_map_sg(dev, sg_req, 1, DMA_TO_DEVICE); - if (!elem) - return -ENOMEM; req_len = sg_dma_len(sg_req); req_dma_addr = sg_dma_address(sg_req); - /* resp */ - sg_resp = &task->smp_task.smp_resp; - elem = dma_map_sg(dev, sg_resp, 1, DMA_FROM_DEVICE); - if (!elem) { - rc = -ENOMEM; - goto err_out_req; - } - resp_len = sg_dma_len(sg_resp); - if ((req_len & 0x3) || (resp_len & 0x3)) { - rc = -EINVAL; - goto err_out_resp; - } - /* create header */ /* dw0 */ hdr->dw0 = cpu_to_le32((port->id << CMD_HDR_PORT_OFF) | @@ -1040,14 +1019,6 @@ static int prep_smp_v3_hw(struct hisi_hba *hisi_hba, hdr->sts_buffer_addr = cpu_to_le64(hisi_sas_status_buf_addr_dma(slot)); return 0; - -err_out_resp: - dma_unmap_sg(dev, &slot->task->smp_task.smp_resp, 1, - DMA_FROM_DEVICE); -err_out_req: - dma_unmap_sg(dev, &slot->task->smp_task.smp_req, 1, - DMA_TO_DEVICE); - return rc; } static int prep_ata_v3_hw(struct hisi_hba *hisi_hba,