[PATCH 4/4] nvme: redirect commands on dying queue

Chao Leng lengchao at huawei.com
Wed Aug 19 06:01:46 EDT 2020



On 2020/8/18 15:11, Christoph Hellwig wrote:
> From: Chao Leng <lengchao at huawei.com>
> 
> If a command send through nvme-multipath failed on a dying queue, resend it
> on another path.
> 
> Signed-off-by: Chao Leng <lengchao at huawei.com>
> [hch: rebased on top of the completion refactoring]
> Signed-off-by: Christoph Hellwig <hch at lst.de>
> Reviewed-by: Sagi Grimberg <sagi at grimberg.me>
> Reviewed-by: Mike Snitzer <snitzer at redhat.com>
> ---
>   drivers/nvme/host/core.c | 9 +++++----
>   1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index 36bb0fe9c7f6f8..a6785b86359fab 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -274,13 +274,14 @@ static inline enum nvme_disposition nvme_decide_disposition(struct request *req)
>   		return COMPLETE;
>   
>   	if (req->cmd_flags & REQ_NVME_MPATH) {
> -		if (nvme_is_path_error(nvme_req(req)->status))
> +		if (nvme_is_path_error(nvme_req(req)->status) ||
> +		    blk_queue_dying(req->q))
>   			return FAILOVER;
> +	} else {
> +		if (blk_queue_dying(req->q))
> +			return COMPLETE;
>   	}
>   
> -	if (blk_queue_dying(req->q))
> -		return COMPLETE;
> -
>   	return RETRY;
>   }

Suggestion:
Do not use blk_noretry_request. The local retry mechanism, which is
defined by nvme protocol, is conflicted with REQ_FAILFAST_TRANSPORT.
blk_noretry_request is not a good choice for nvme, even for SCSI,
this is not a good choice too, so SCSI does not use this MACRO.
We can seperate REQ_FAILFAST_TRANSPORT with other FAILFAST flag.
For REQ_FAILFAST_TRANSPORT, do local retry for non path error.
For other FAILFAST flag, complete request with error code immediately.
---
  drivers/nvme/host/core.c | 12 +++++++++++-
  1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index a6785b86359f..cfd870780353 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -257,6 +257,16 @@ static void nvme_retry_req(struct request *req)
         blk_mq_delay_kick_requeue_list(req->q, delay);
  }

+static inline bool nvme_noretry_request(struct request *req)
+{
+       if (req->cmd_flags & (REQ_FAILFAST_DRIVER | REQ_FAILFAST_DEV))
+               return true;
+       if ((req->cmd_flags & REQ_FAILFAST_TRANSPORT) &&
+           nvme_is_path_error(nvme_req(req)->status))
+               return true;
+       return false;
+}
+
  enum nvme_disposition {
         COMPLETE,
         RETRY,
@@ -268,7 +278,7 @@ static inline enum nvme_disposition nvme_decide_disposition(struct request *req)
         if (likely(nvme_req(req)->status == 0))
                 return COMPLETE;

-       if (blk_noretry_request(req) ||
+       if (nvme_noretry_request(req) ||
             (nvme_req(req)->status & NVME_SC_DNR) ||
             nvme_req(req)->retries >= nvme_max_retries)
                 return COMPLETE;
-- 



More information about the Linux-nvme mailing list