From patchwork Thu Jan 4 22:46:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 10145751 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 639ED601A1 for ; Thu, 4 Jan 2018 22:51:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C18BF288CA for ; Thu, 4 Jan 2018 22:51:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B239E288E8; Thu, 4 Jan 2018 22:51:00 +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 27F5728772 for ; Thu, 4 Jan 2018 22:51:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753240AbeADWu7 (ORCPT ); Thu, 4 Jan 2018 17:50:59 -0500 Received: from mga01.intel.com ([192.55.52.88]:32449 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753199AbeADWu7 (ORCPT ); Thu, 4 Jan 2018 17:50:59 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 04 Jan 2018 14:50:58 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,316,1511856000"; d="scan'208";a="16875986" Received: from unknown (HELO localhost.lm.intel.com) ([10.232.112.44]) by FMSMGA003.fm.intel.com with ESMTP; 04 Jan 2018 14:50:57 -0800 From: Keith Busch To: Linux Block , Linux NVMe , Device Mapper , Christoph Hellwig , Mike Snitzer , Jens Axboe Cc: Bart VanAssche , James Smart , "Martin K . Petersen" , Hannes Reinecke , Sagi Grimberg , Keith Busch Subject: [PATCH 2/5] nvme/multipath: Consult blk_status_t for failover Date: Thu, 4 Jan 2018 15:46:20 -0700 Message-Id: <20180104224623.8944-3-keith.busch@intel.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20180104224623.8944-1-keith.busch@intel.com> References: <20180104224623.8944-1-keith.busch@intel.com> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This removes nvme multipath's specific status decoding to see if failover is needed, using the generic blk_status_t that was translated earlier. This abstraction from the raw NVMe status means nvme status decoding exists in just one place. Signed-off-by: Keith Busch Acked-by: Mike Snitzer --- drivers/nvme/host/core.c | 9 +++++---- drivers/nvme/host/multipath.c | 44 ++++++++----------------------------------- drivers/nvme/host/nvme.h | 4 ++-- 3 files changed, 15 insertions(+), 42 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index f1cf1f6c5b28..4afc681f7089 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -196,8 +196,10 @@ static inline bool nvme_req_needs_retry(struct request *req) void nvme_complete_rq(struct request *req) { - if (unlikely(nvme_req(req)->status && nvme_req_needs_retry(req))) { - if (nvme_req_needs_failover(req)) { + blk_status_t status = nvme_error_status(req); + + if (unlikely(status != BLK_STS_OK && nvme_req_needs_retry(req))) { + if (nvme_req_needs_failover(req, status)) { nvme_failover_req(req); return; } @@ -208,8 +210,7 @@ void nvme_complete_rq(struct request *req) return; } } - - blk_mq_end_request(req, nvme_error_status(req)); + blk_mq_end_request(req, status); } EXPORT_SYMBOL_GPL(nvme_complete_rq); diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index 1218a9fca846..ae9abb600c0f 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -33,46 +33,18 @@ void nvme_failover_req(struct request *req) kblockd_schedule_work(&ns->head->requeue_work); } -bool nvme_req_needs_failover(struct request *req) +bool nvme_req_needs_failover(struct request *req, blk_status_t error) { if (!(req->cmd_flags & REQ_NVME_MPATH)) return false; - switch (nvme_req(req)->status & 0x7ff) { - /* - * Generic command status: - */ - case NVME_SC_INVALID_OPCODE: - case NVME_SC_INVALID_FIELD: - case NVME_SC_INVALID_NS: - case NVME_SC_LBA_RANGE: - case NVME_SC_CAP_EXCEEDED: - case NVME_SC_RESERVATION_CONFLICT: - return false; - - /* - * I/O command set specific error. Unfortunately these values are - * reused for fabrics commands, but those should never get here. - */ - case NVME_SC_BAD_ATTRIBUTES: - case NVME_SC_INVALID_PI: - case NVME_SC_READ_ONLY: - case NVME_SC_ONCS_NOT_SUPPORTED: - WARN_ON_ONCE(nvme_req(req)->cmd->common.opcode == - nvme_fabrics_command); - return false; - - /* - * Media and Data Integrity Errors: - */ - case NVME_SC_WRITE_FAULT: - case NVME_SC_READ_ERROR: - case NVME_SC_GUARD_CHECK: - case NVME_SC_APPTAG_CHECK: - case NVME_SC_REFTAG_CHECK: - case NVME_SC_COMPARE_FAILED: - case NVME_SC_ACCESS_DENIED: - case NVME_SC_UNWRITTEN_BLOCK: + switch (error) { + case BLK_STS_NOTSUPP: + case BLK_STS_NOSPC: + case BLK_STS_TARGET: + case BLK_STS_NEXUS: + case BLK_STS_MEDIUM: + case BLK_STS_PROTECTION: return false; } diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index ea1aa5283e8e..cf8548c1d7ec 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -401,7 +401,7 @@ extern const struct block_device_operations nvme_ns_head_ops; #ifdef CONFIG_NVME_MULTIPATH void nvme_failover_req(struct request *req); -bool nvme_req_needs_failover(struct request *req); +bool nvme_req_needs_failover(struct request *req, blk_status_t error); void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl); int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl,struct nvme_ns_head *head); void nvme_mpath_add_disk(struct nvme_ns_head *head); @@ -421,7 +421,7 @@ struct nvme_ns *nvme_find_path(struct nvme_ns_head *head); static inline void nvme_failover_req(struct request *req) { } -static inline bool nvme_req_needs_failover(struct request *req) +static inline bool nvme_req_needs_failover(struct request *req, blk_status_t error) { return false; }