From patchwork Thu Jun 22 02:16:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uma Krishnan X-Patchwork-Id: 9803345 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 075AC60329 for ; Thu, 22 Jun 2017 02:17:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EEE4528534 for ; Thu, 22 Jun 2017 02:17:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E2B372855E; Thu, 22 Jun 2017 02:17:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 47ED028534 for ; Thu, 22 Jun 2017 02:17:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752399AbdFVCRC (ORCPT ); Wed, 21 Jun 2017 22:17:02 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:53095 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751934AbdFVCRC (ORCPT ); Wed, 21 Jun 2017 22:17:02 -0400 Received: from pps.filterd (m0098414.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.20/8.16.0.20) with SMTP id v5M2EhlC131417 for ; Wed, 21 Jun 2017 22:17:01 -0400 Received: from e31.co.us.ibm.com (e31.co.us.ibm.com [32.97.110.149]) by mx0b-001b2d01.pphosted.com with ESMTP id 2b7ts7kdj6-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Wed, 21 Jun 2017 22:17:01 -0400 Received: from localhost by e31.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 21 Jun 2017 20:17:00 -0600 Received: from b03cxnp08028.gho.boulder.ibm.com (9.17.130.20) by e31.co.us.ibm.com (192.168.1.131) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 21 Jun 2017 20:16:58 -0600 Received: from b03ledav001.gho.boulder.ibm.com (b03ledav001.gho.boulder.ibm.com [9.17.130.232]) by b03cxnp08028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v5M2Gvtg22872172; Wed, 21 Jun 2017 19:16:57 -0700 Received: from b03ledav001.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1EBE16E038; Wed, 21 Jun 2017 20:16:57 -0600 (MDT) Received: from p8tul1-build.aus.stglabs.ibm.com (unknown [9.3.141.206]) by b03ledav001.gho.boulder.ibm.com (Postfix) with ESMTP id 962BA6E03F; Wed, 21 Jun 2017 20:16:56 -0600 (MDT) From: Uma Krishnan To: linux-scsi@vger.kernel.org, James Bottomley , "Martin K. Petersen" , "Matthew R. Ochs" , "Manoj N. Kumar" Cc: linuxppc-dev@lists.ozlabs.org, Ian Munsie , Andrew Donnellan , Frederic Barrat , Christophe Lombard Subject: [PATCH 17/17] cxlflash: Update TMF command processing Date: Wed, 21 Jun 2017 21:16:54 -0500 X-Mailer: git-send-email 2.1.0 In-Reply-To: <1498097563-8680-1-git-send-email-ukrishn@linux.vnet.ibm.com> References: <1498097563-8680-1-git-send-email-ukrishn@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 17062202-8235-0000-0000-00000BC52524 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00007269; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000214; SDB=6.00878073; UDB=6.00437482; IPR=6.00658213; BA=6.00005434; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00015913; XFM=3.00000015; UTC=2017-06-22 02:16:59 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17062202-8236-0000-0000-00003C64F9CE Message-Id: <1498097814-9301-1-git-send-email-ukrishn@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-06-22_01:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=0 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1703280000 definitions=main-1706220037 Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: "Matthew R. Ochs" Currently, the SCSI command presented to the device reset handler is used to send TMFs to the AFU for a device reset. This behavior is incorrect as the command presented is an actual command and not a special notification. As such, it should only be used for reference and not be acted upon. Additionally, the existing TMF transmission routine does not account for actual errors from the hardware, only reflecting failure when a timeout occurs. This can lead to a condition where the device reset handler is presented with a false 'success'. Update send_tmf() to dynamically allocate a private command for sending the TMF command and properly reflect failure when the completed command indicates an error or was aborted. Detect TMF commands during response processing and avoid scsi_done() for these types of commands. Lastly, update comments in the TMF processing paths to describe the new behavior. Signed-off-by: Matthew R. Ochs Signed-off-by: Uma Krishnan --- drivers/scsi/cxlflash/main.c | 65 ++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 21 deletions(-) diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 4338982..7a787b6 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -155,9 +155,10 @@ static void process_cmd_err(struct afu_cmd *cmd, struct scsi_cmnd *scp) * cmd_complete() - command completion handler * @cmd: AFU command that has completed. * - * Prepares and submits command that has either completed or timed out to - * the SCSI stack. Checks AFU command back into command pool for non-internal - * (cmd->scp populated) commands. + * For SCSI commands this routine prepares and submits commands that have + * either completed or timed out to the SCSI stack. For internal commands + * (TMF or AFU), this routine simply notifies the originator that the + * command has completed. */ static void cmd_complete(struct afu_cmd *cmd) { @@ -167,7 +168,6 @@ static void cmd_complete(struct afu_cmd *cmd) struct cxlflash_cfg *cfg = afu->parent; struct device *dev = &cfg->dev->dev; struct hwq *hwq = get_hwq(afu, cmd->hwq_index); - bool cmd_is_tmf; spin_lock_irqsave(&hwq->hsq_slock, lock_flags); list_del(&cmd->list); @@ -180,19 +180,14 @@ static void cmd_complete(struct afu_cmd *cmd) else scp->result = (DID_OK << 16); - cmd_is_tmf = cmd->cmd_tmf; - dev_dbg_ratelimited(dev, "%s:scp=%p result=%08x ioasc=%08x\n", __func__, scp, scp->result, cmd->sa.ioasc); - scp->scsi_done(scp); - - if (cmd_is_tmf) { - spin_lock_irqsave(&cfg->tmf_slock, lock_flags); - cfg->tmf_active = false; - wake_up_all_locked(&cfg->tmf_waitq); - spin_unlock_irqrestore(&cfg->tmf_slock, lock_flags); - } + } else if (cmd->cmd_tmf) { + spin_lock_irqsave(&cfg->tmf_slock, lock_flags); + cfg->tmf_active = false; + wake_up_all_locked(&cfg->tmf_waitq); + spin_unlock_irqrestore(&cfg->tmf_slock, lock_flags); } else complete(&cmd->cevent); } @@ -206,8 +201,10 @@ static void cmd_complete(struct afu_cmd *cmd) */ static void flush_pending_cmds(struct hwq *hwq) { + struct cxlflash_cfg *cfg = hwq->afu->parent; struct afu_cmd *cmd, *tmp; struct scsi_cmnd *scp; + ulong lock_flags; list_for_each_entry_safe(cmd, tmp, &hwq->pending_cmds, list) { /* Bypass command when on a doneq, cmd_complete() will handle */ @@ -222,7 +219,15 @@ static void flush_pending_cmds(struct hwq *hwq) scp->scsi_done(scp); } else { cmd->cmd_aborted = true; - complete(&cmd->cevent); + + if (cmd->cmd_tmf) { + spin_lock_irqsave(&cfg->tmf_slock, lock_flags); + cfg->tmf_active = false; + wake_up_all_locked(&cfg->tmf_waitq); + spin_unlock_irqrestore(&cfg->tmf_slock, + lock_flags); + } else + complete(&cmd->cevent); } } } @@ -455,24 +460,35 @@ static u32 cmd_to_target_hwq(struct Scsi_Host *host, struct scsi_cmnd *scp, /** * send_tmf() - sends a Task Management Function (TMF) * @afu: AFU to checkout from. - * @scp: SCSI command from stack. + * @scp: SCSI command from stack describing target. * @tmfcmd: TMF command to send. * * Return: - * 0 on success, SCSI_MLQUEUE_HOST_BUSY on failure + * 0 on success, SCSI_MLQUEUE_HOST_BUSY or -errno on failure */ static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd) { struct Scsi_Host *host = scp->device->host; struct cxlflash_cfg *cfg = shost_priv(host); - struct afu_cmd *cmd = sc_to_afucz(scp); + struct afu_cmd *cmd = NULL; struct device *dev = &cfg->dev->dev; int hwq_index = cmd_to_target_hwq(host, scp, afu); struct hwq *hwq = get_hwq(afu, hwq_index); + char *buf = NULL; ulong lock_flags; int rc = 0; ulong to; + buf = kzalloc(sizeof(*cmd) + __alignof__(*cmd) - 1, GFP_KERNEL); + if (unlikely(!buf)) { + dev_err(dev, "%s: no memory for command\n", __func__); + rc = -ENOMEM; + goto out; + } + + cmd = (struct afu_cmd *)PTR_ALIGN(buf, __alignof__(*cmd)); + INIT_LIST_HEAD(&cmd->queue); + /* When Task Management Function is active do not send another */ spin_lock_irqsave(&cfg->tmf_slock, lock_flags); if (cfg->tmf_active) @@ -482,7 +498,6 @@ static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd) cfg->tmf_active = true; spin_unlock_irqrestore(&cfg->tmf_slock, lock_flags); - cmd->scp = scp; cmd->parent = afu; cmd->cmd_tmf = true; cmd->hwq_index = hwq_index; @@ -511,12 +526,20 @@ static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd) cfg->tmf_slock, to); if (!to) { - cfg->tmf_active = false; dev_err(dev, "%s: TMF timed out\n", __func__); - rc = -1; + rc = -ETIMEDOUT; + } else if (cmd->cmd_aborted) { + dev_err(dev, "%s: TMF aborted\n", __func__); + rc = -EAGAIN; + } else if (cmd->sa.ioasc) { + dev_err(dev, "%s: TMF failed ioasc=%08x\n", + __func__, cmd->sa.ioasc); + rc = -EIO; } + cfg->tmf_active = false; spin_unlock_irqrestore(&cfg->tmf_slock, lock_flags); out: + kfree(buf); return rc; }