From patchwork Fri Dec 8 17:16:46 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 121201 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp863481qgn; Fri, 8 Dec 2017 08:31:29 -0800 (PST) X-Google-Smtp-Source: AGs4zMZ5i6vNPCpkn+/5ha32RVl76IBL1K3odA9bhaDrN422s0Bfks5SLjsNL8595KRGD5p4PlGt X-Received: by 10.159.234.75 with SMTP id c11mr32196784plr.422.1512750689335; Fri, 08 Dec 2017 08:31:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512750689; cv=none; d=google.com; s=arc-20160816; b=xkYz3idpO4h9c1DRNoFeNC5lXp6t6mX/pEkc4tL8OKDHVvAo4KnS8nbcFzDjFcYK62 ZJgv3YVgZgwsUJhYuv+ik28qFJiqL1KZWQRIymkKw87I6cTMC9dHgK4uuVlToa04qUT2 tUFFeJYyG/aMPyjjjNMYSD2I3xStndFsvxglnx9lLk8d9oq24ZO6kY597BaodmB3fpLj OI+2v/fcJ8t43bl3vRWnMUYRkkfblQQYjuNguLZ0B1UWhDP4rqsoAYWrubORiW/P4orn J4Xg+G3UrOpk3H+G84A/DE6hXlNsnF7XdGReHVq+JdFW0C4O8h1+0QuGzB6bPfKjQR8n /YYA== 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=fTC0XElzeX9IeIy41PHd2eeRK/SM/kbJNXPkSxgTjcM=; b=B6mDXMneLDuUdwEAEkC+3gZTVnJJ89t6TYJH5jDQTFssk5w6K0xgUCGOTV4+H/1u/q Jm7z+Y2AV+cLCPzapm5vvgYtMLZWCyKwonS3XGt1IcoafkMHhc8j7Thi0L2FuMX4+UOb 11z2YFBKwSQFEA8AjUHQM5gf+p9eNkWWMGlt3Ehqkr2FhXvqwR2McVPBuEY/UaBa19xa 3c7aNvOYlxuldloIzXcJhyGy0DSUeolzBUcOKL4GiP89WStplhUV262K0f5VL8hb7kut lMMuWR+msi/0Z1zLwT5pp1mE3bldafjk7zlXivAk1GBUkHuT8vwlPgheOtBH3rqQo922 EvfQ== 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 o6si2289947pls.300.2017.12.08.08.31.28; Fri, 08 Dec 2017 08:31:29 -0800 (PST) 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 S1752891AbdLHQb1 (ORCPT + 18 others); Fri, 8 Dec 2017 11:31:27 -0500 Received: from szxga06-in.huawei.com ([45.249.212.32]:36073 "EHLO huawei.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1754080AbdLHQbD (ORCPT ); Fri, 8 Dec 2017 11:31:03 -0500 Received: from DGGEMS407-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id 78CECFBC8A87A; Sat, 9 Dec 2017 00:30:50 +0800 (CST) Received: from localhost.localdomain (10.67.212.75) by DGGEMS407-HUB.china.huawei.com (10.3.19.207) with Microsoft SMTP Server id 14.3.361.1; Sat, 9 Dec 2017 00:30:41 +0800 From: John Garry To: , CC: , , , Xiaofei Tan , "John Garry" Subject: [PATCH 15/19] scsi: hisi_sas: judge result of internal abort Date: Sat, 9 Dec 2017 01:16:46 +0800 Message-ID: <1512753410-50924-16-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1512753410-50924-1-git-send-email-john.garry@huawei.com> References: <1512753410-50924-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: Xiaofei Tan Normally, hardware should ensure that internal abort timeout will never happen. If happen, it would be an SoC failure. What's more, HW will not process any other commands if an internal abort hasn't return CQ, and they will time out also. So, we should judge the result of internal abort in SCSI EH, if it is failed, we should give up to do TMF/softreset and return failure to the upper layer directly. This patch do following things to achieve this. 1. When internal abort timeout happened, we set return value to -EIO in hisi_sas_internal_task_abort(). 2. If prep_abort() is not support, let hisi_sas_internal_task_abort() return TMF_RESP_FUNC_FAILED. 3. If hisi_sas_internal_task_abort() return an negative number, it can be thought that it not executed properly or internal abort timeout. Then we won't do behind TMF or softreset, and return failure directly. Signed-off-by: Xiaofei Tan Signed-off-by: John Garry --- drivers/scsi/hisi_sas/hisi_sas_main.c | 38 ++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 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 7446a39..1b9c48c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1184,6 +1184,11 @@ static int hisi_sas_abort_task(struct sas_task *task) rc2 = hisi_sas_internal_task_abort(hisi_hba, device, HISI_SAS_INT_ABT_CMD, tag); + if (rc2 < 0) { + dev_err(dev, "abort task: internal abort (%d)\n", rc2); + return TMF_RESP_FUNC_FAILED; + } + /* * If the TMF finds that the IO is not in the device and also * the internal abort does not succeed, then it is safe to @@ -1201,8 +1206,12 @@ static int hisi_sas_abort_task(struct sas_task *task) } else if (task->task_proto & SAS_PROTOCOL_SATA || task->task_proto & SAS_PROTOCOL_STP) { if (task->dev->dev_type == SAS_SATA_DEV) { - hisi_sas_internal_task_abort(hisi_hba, device, - HISI_SAS_INT_ABT_DEV, 0); + rc = hisi_sas_internal_task_abort(hisi_hba, device, + HISI_SAS_INT_ABT_DEV, 0); + if (rc < 0) { + dev_err(dev, "abort task: internal abort failed\n"); + goto out; + } hisi_sas_dereg_device(hisi_hba, device); rc = hisi_sas_softreset_ata_disk(device); } @@ -1213,7 +1222,8 @@ static int hisi_sas_abort_task(struct sas_task *task) rc = hisi_sas_internal_task_abort(hisi_hba, device, HISI_SAS_INT_ABT_CMD, tag); - if (rc == TMF_RESP_FUNC_FAILED && task->lldd_task) { + if (((rc < 0) || (rc == TMF_RESP_FUNC_FAILED)) && + task->lldd_task) { spin_lock_irqsave(&hisi_hba->lock, flags); hisi_sas_do_release_task(hisi_hba, task, slot); spin_unlock_irqrestore(&hisi_hba->lock, flags); @@ -1263,15 +1273,20 @@ static int hisi_sas_I_T_nexus_reset(struct domain_device *device) { struct hisi_sas_device *sas_dev = device->lldd_dev; struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); - unsigned long flags; + struct device *dev = hisi_hba->dev; int rc = TMF_RESP_FUNC_FAILED; + unsigned long flags; if (sas_dev->dev_status != HISI_SAS_DEV_EH) return TMF_RESP_FUNC_FAILED; sas_dev->dev_status = HISI_SAS_DEV_NORMAL; - hisi_sas_internal_task_abort(hisi_hba, device, + rc = hisi_sas_internal_task_abort(hisi_hba, device, HISI_SAS_INT_ABT_DEV, 0); + if (rc < 0) { + dev_err(dev, "I_T nexus reset: internal abort (%d)\n", rc); + return TMF_RESP_FUNC_FAILED; + } hisi_sas_dereg_device(hisi_hba, device); rc = hisi_sas_debug_I_T_nexus_reset(device); @@ -1299,8 +1314,10 @@ static int hisi_sas_lu_reset(struct domain_device *device, u8 *lun) /* Clear internal IO and then hardreset */ rc = hisi_sas_internal_task_abort(hisi_hba, device, HISI_SAS_INT_ABT_DEV, 0); - if (rc == TMF_RESP_FUNC_FAILED) + if (rc < 0) { + dev_err(dev, "lu_reset: internal abort failed\n"); goto out; + } hisi_sas_dereg_device(hisi_hba, device); phy = sas_get_local_phy(device); @@ -1497,8 +1514,14 @@ static int hisi_sas_query_task(struct sas_task *task) struct device *dev = hisi_hba->dev; int res; + /* + * The interface is not realized means this HW don't support internal + * abort, or don't need to do internal abort. Then here, we return + * TMF_RESP_FUNC_FAILED and let other steps go on, which depends that + * the internal abort has been executed and returned CQ. + */ if (!hisi_hba->hw->prep_abort) - return -EOPNOTSUPP; + return TMF_RESP_FUNC_FAILED; task = sas_alloc_slow_task(GFP_KERNEL); if (!task) @@ -1530,6 +1553,7 @@ static int hisi_sas_query_task(struct sas_task *task) if (slot) slot->task = NULL; dev_err(dev, "internal task abort: timeout and not done.\n"); + res = -EIO; goto exit; } else dev_err(dev, "internal task abort: timeout.\n");