From patchwork Thu Nov 15 17:56:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 10684789 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4B2973CF1 for ; Thu, 15 Nov 2018 17:59:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 382B02CE14 for ; Thu, 15 Nov 2018 17:59:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2C05F2CD77; Thu, 15 Nov 2018 17:59:54 +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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable 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 C54382CEA2 for ; Thu, 15 Nov 2018 17:59:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388573AbeKPEIl (ORCPT ); Thu, 15 Nov 2018 23:08:41 -0500 Received: from mga11.intel.com ([192.55.52.93]:61131 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726910AbeKPEIl (ORCPT ); Thu, 15 Nov 2018 23:08:41 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Nov 2018 09:59:51 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,237,1539673200"; d="scan'208";a="280206594" Received: from unknown (HELO localhost.lm.intel.com) ([10.232.112.69]) by fmsmga005.fm.intel.com with ESMTP; 15 Nov 2018 09:59:51 -0800 From: Keith Busch To: linux-scsi@vger.kernel.org, linux-block@vger.kernel.org Cc: Jens Axboe , Martin Petersen , Bart Van Assche , Keith Busch Subject: [PATCH 2/3] scsi: Do not rely on blk-mq for double completions Date: Thu, 15 Nov 2018 10:56:25 -0700 Message-Id: <20181115175626.13293-2-keith.busch@intel.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20181115175626.13293-1-keith.busch@intel.com> References: <20181115175626.13293-1-keith.busch@intel.com> 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 The scsi timeout error handling had been directly updating the request state to prevent a natural completion and error handling from completing the same request twice. Fix this layering violation by having scsi control the fate of its commands with scsi owned flags rather than use blk-mq's. Signed-off-by: Keith Busch --- drivers/scsi/scsi_error.c | 17 +++-------------- drivers/scsi/scsi_lib.c | 6 +++++- include/scsi/scsi_cmnd.h | 5 ++++- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index c736d61b1648..f89e829a1c51 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -199,6 +199,9 @@ scsi_abort_command(struct scsi_cmnd *scmd) return FAILED; } + if (test_and_set_bit(__SCMD_COMPLETE, &scmd->flags)) + return SUCCESS; + spin_lock_irqsave(shost->host_lock, flags); if (shost->eh_deadline != -1 && !shost->last_reset) shost->last_reset = jiffies; @@ -296,20 +299,6 @@ enum blk_eh_timer_return scsi_times_out(struct request *req) rtn = host->hostt->eh_timed_out(scmd); if (rtn == BLK_EH_DONE) { - /* - * For blk-mq, we must set the request state to complete now - * before sending the request to the scsi error handler. This - * will prevent a use-after-free in the event the LLD manages - * to complete the request before the error handler finishes - * processing this timed out request. - * - * If the request was already completed, then the LLD beat the - * time out handler from transferring the request to the scsi - * error handler. In that case we can return immediately as no - * further action is required. - */ - if (req->q->mq_ops && !blk_mq_mark_complete(req)) - return rtn; if (scsi_abort_command(scmd) != SUCCESS) { set_host_byte(scmd, DID_TIME_OUT); scsi_eh_scmd_add(scmd); diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index c7fccbb8f554..1e74137f1073 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -2044,8 +2044,11 @@ static int scsi_mq_prep_fn(struct request *req) static void scsi_mq_done(struct scsi_cmnd *cmd) { + if (test_and_set_bit(__SCMD_COMPLETE, &cmd->flags)) + return; trace_scsi_dispatch_cmd_done(cmd); - blk_mq_complete_request(cmd->request); + if (unlikely(!blk_mq_complete_request(cmd->request))) + clear_bit(__SCMD_COMPLETE, &cmd->flags); } static void scsi_mq_put_budget(struct blk_mq_hw_ctx *hctx) @@ -2104,6 +2107,7 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, goto out_dec_host_busy; req->rq_flags |= RQF_DONTPREP; } else { + cmd->flags &= ~SCMD_COMPLETE; blk_mq_start_request(req); } diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index c891ada3c5c2..acef13c628d3 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -58,6 +58,9 @@ struct scsi_pointer { #define SCMD_TAGGED (1 << 0) #define SCMD_UNCHECKED_ISA_DMA (1 << 1) #define SCMD_INITIALIZED (1 << 2) + +#define __SCMD_COMPLETE 3 +#define SCMD_COMPLETE (1 << __SCMD_COMPLETE) /* flags preserved across unprep / reprep */ #define SCMD_PRESERVED_FLAGS (SCMD_UNCHECKED_ISA_DMA | SCMD_INITIALIZED) @@ -144,7 +147,7 @@ struct scsi_cmnd { * to be at an address < 16Mb). */ int result; /* Status code from lower level driver */ - int flags; /* Command flags */ + unsigned long flags; /* Command flags */ unsigned char tag; /* SCSI-II queued command tag */ };