From patchwork Sun Feb 28 13:32:35 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yaniv Gardi X-Patchwork-Id: 8446631 Return-Path: X-Original-To: patchwork-linux-arm-msm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 0123E9F314 for ; Sun, 28 Feb 2016 13:37:11 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 614612035E for ; Sun, 28 Feb 2016 13:37:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 787B120122 for ; Sun, 28 Feb 2016 13:37:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757690AbcB1NdJ (ORCPT ); Sun, 28 Feb 2016 08:33:09 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:58951 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757246AbcB1NdH (ORCPT ); Sun, 28 Feb 2016 08:33:07 -0500 Received: from smtp.codeaurora.org (localhost [127.0.0.1]) by smtp.codeaurora.org (Postfix) with ESMTP id B9EA3608A9; Sun, 28 Feb 2016 13:33:06 +0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 1000) id AC9DA608AA; Sun, 28 Feb 2016 13:33:06 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from lx-ygardi.mea.qualcomm.com (unknown [185.23.60.4]) (using TLSv1.1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: ygardi@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 8792C608B0; Sun, 28 Feb 2016 13:33:03 +0000 (UTC) From: Yaniv Gardi To: James.Bottomley@HansenPartnership.com Cc: linux-kernel@vger.kernel.org, linux-scsi@vger.kernel.org, linux-arm-msm@vger.kernel.org, santoshsy@gmail.com, linux-scsi-owner@vger.kernel.org, ygardi@codeaurora.org, Gilad Broner , Vinayak Holikatti , "James E.J. Bottomley" , "Martin K. Petersen" Subject: [PATCH v5 03/15] scsi: ufs: implement scsi host timeout handler Date: Sun, 28 Feb 2016 15:32:35 +0200 Message-Id: <1456666367-11418-4-git-send-email-ygardi@codeaurora.org> X-Mailer: git-send-email 1.8.5.2 In-Reply-To: <1456666367-11418-1-git-send-email-ygardi@codeaurora.org> References: <1456666367-11418-1-git-send-email-ygardi@codeaurora.org> X-Virus-Scanned: ClamAV using ClamSMTP Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP A race condition exists between request requeueing and scsi layer error handling: When UFS driver queuecommand returns a busy status for a request, it will be requeued and its tag will be freed and set to -1. At the same time it is possible that the request will timeout and scsi layer will start error handling for it. The scsi layer reuses the request and its tag to send error related commands to the device, however its tag is no longer valid. As this request was never really sent to the device, there is no point to start error handling with the device. Implement the scsi error handling timeout callback and bypass SCSI error handling for request that were not actually sent to the device. For such requests simply reset the block layer timer. Otherwise, let SCSI layer perform the usual error handling. Signed-off-by: Gilad Broner Signed-off-by: Yaniv Gardi --- drivers/scsi/ufs/ufshcd.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index de7280c..3400ceb 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -4568,6 +4568,41 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie) ufshcd_probe_hba(hba); } +static enum blk_eh_timer_return ufshcd_eh_timed_out(struct scsi_cmnd *scmd) +{ + unsigned long flags; + struct Scsi_Host *host; + struct ufs_hba *hba; + int index; + bool found = false; + + if (!scmd || !scmd->device || !scmd->device->host) + return BLK_EH_NOT_HANDLED; + + host = scmd->device->host; + hba = shost_priv(host); + if (!hba) + return BLK_EH_NOT_HANDLED; + + spin_lock_irqsave(host->host_lock, flags); + + for_each_set_bit(index, &hba->outstanding_reqs, hba->nutrs) { + if (hba->lrb[index].cmd == scmd) { + found = true; + break; + } + } + + spin_unlock_irqrestore(host->host_lock, flags); + + /* + * Bypass SCSI error handling and reset the block layer timer if this + * SCSI command was not actually dispatched to UFS driver, otherwise + * let SCSI layer handle the error as usual. + */ + return found ? BLK_EH_NOT_HANDLED : BLK_EH_RESET_TIMER; +} + static struct scsi_host_template ufshcd_driver_template = { .module = THIS_MODULE, .name = UFSHCD, @@ -4580,6 +4615,7 @@ static struct scsi_host_template ufshcd_driver_template = { .eh_abort_handler = ufshcd_abort, .eh_device_reset_handler = ufshcd_eh_device_reset_handler, .eh_host_reset_handler = ufshcd_eh_host_reset_handler, + .eh_timed_out = ufshcd_eh_timed_out, .this_id = -1, .sg_tablesize = SG_ALL, .cmd_per_lun = UFSHCD_CMD_PER_LUN,