From: Mike Snitzer on gitlab.com Merge Request: https://gitlab.com/cki-project/kernel-ark/-/merge_requests/1024
BZ: 1948690 Upstream Status: RHEL-only
Forward-port RHEL8 NVMe changes to RHEL9. These changes were rejected by Christoph Hellwig (hch is one of upstream's 4 NVMe maintainers). The other (3) upstream NVMe maintainers don't have a problem with these changes, but Christoph is hostile toward any changes that make NVMe work better with dm-multipath (because he wants everyone to use NVMe's native multipathing, doesn't care that others have reasons why they want to use dm-multipath).
So unfortunately we need to just keep carrying these changes in RHEL. Can revisit getting these changes to land upstream in time for RHEL10, but I don't care to engage upstream (specifically hch) on this topic at this point in time.
Thankfully these NVMe changes are _not_ intrusive, have proven stable/useful in RHEL8 and were easily forward-ported from RHEL8 to RHEL9.
Signed-off-by: Mike Snitzer snitzer@redhat.com
From: Mike Snitzer snitzer@redhat.com
nvme: Return BLK_STS_TARGET if the DNR bit is set
BZ: 1948690 Upstream Status: RHEL-only
Signed-off-by: Mike Snitzer snitzer@redhat.com
rhel-8.git commit ef4ab90c12db5e0e50800ec323736b95be7a6ff5 Author: Mike Snitzer snitzer@redhat.com Date: Tue Aug 25 21:52:45 2020 -0400
[nvme] nvme: Return BLK_STS_TARGET if the DNR bit is set
Message-id: 20200825215248.2291-8-snitzer@redhat.com Patchwork-id: 325178 Patchwork-instance: patchwork O-Subject: [RHEL8.3 PATCH 07/10] nvme: Return BLK_STS_TARGET if the DNR bit is set Bugzilla: 1843515 RH-Acked-by: David Milburn dmilburn@redhat.com RH-Acked-by: Gopal Tiwari gtiwari@redhat.com RH-Acked-by: Ewan Milne emilne@redhat.com
BZ: 1843515 Upstream Status: RHEL-only
If the DNR bit is set we should not retry the command, even if the standard status evaluation indicates so.
SUSE is carrying this patch in their kernel: https://lwn.net/Articles/800370/
Based on patch posted for upstream inclusion but rejected: v1: https://lore.kernel.org/linux-nvme/20190806111036.113233-1-hare@suse.de/ v2: https://lore.kernel.org/linux-nvme/20190807071208.101882-1-hare@suse.de/ v2-keith: https://lore.kernel.org/linux-nvme/20190807144725.GB25621@localhost.localdom... v3: https://lore.kernel.org/linux-nvme/20190812075147.79598-1-hare@suse.de/ v3-keith: https://lore.kernel.org/linux-nvme/20190813141510.GB32686@localhost.localdom...
This commit's change is basically "v3-keith".
Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Frantisek Hrbata fhrbata@redhat.com
diff a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -237,6 +237,9 @@ static void nvme_delete_ctrl_sync(struct nvme_ctrl *ctrl)
static blk_status_t nvme_error_status(u16 status) { + if (unlikely(status & NVME_SC_DNR)) + return BLK_STS_TARGET; + switch (status & 0x7ff) { case NVME_SC_SUCCESS: return BLK_STS_OK;
-- https://gitlab.com/cki-project/kernel-ark/-/merge_requests/1024
From: Mike Snitzer snitzer@redhat.com
nvme: allow local retry and proper failover for REQ_FAILFAST_TRANSPORT
BZ: 1948690 Upstream Status: RHEL-only
This commit offers a more minimalist version of these 2 rhel-8.git commits: f8fb6ea1226e2 [nvme] nvme: update failover handling to work with REQ_FAILFAST_TRANSPORT 7dadadb072515 [nvme] nvme: allow retry for requests with REQ_FAILFAST_TRANSPORT set
REQ_FAILFAST_TRANSPORT is set by upper layer software that handles multipathing. Unlike SCSI, NVMe's error handling was specifically designed to handle local retry for non-path errors. As such, allow NVMe's local retry mechanism to be used for requests marked with REQ_FAILFAST_TRANSPORT.
In this way, the mechanism of NVMe multipath or other multipath are now equivalent. The mechanism is: non path related error will be retried locally, path related error is handled by multipath.
Also, introduce FAILUP handling for REQ_FAILFAST_TRANSPORT. Update NVMe to allow failover of requests marked with either REQ_NVME_MPATH or REQ_FAILFAST_TRANSPORT. This allows such requests to be given a disposition of either FAILOVER or FAILUP respectively.
nvme_complete_rq() is updated to call nvme_failup_req() if nvme_decide_disposition() returns FAILUP. nvme_failup_req() ensures the request is completed with a retryable path error.
Signed-off-by: Mike Snitzer snitzer@redhat.com
diff a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -299,6 +299,7 @@ enum nvme_disposition { COMPLETE, RETRY, FAILOVER, + FAILUP, };
static inline enum nvme_disposition nvme_decide_disposition(struct request *req) @@ -306,15 +307,16 @@ 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 ((req->cmd_flags & (REQ_FAILFAST_DEV | REQ_FAILFAST_DRIVER)) || (nvme_req(req)->status & NVME_SC_DNR) || nvme_req(req)->retries >= nvme_max_retries) return COMPLETE;
- if (req->cmd_flags & REQ_NVME_MPATH) { + if (req->cmd_flags & (REQ_NVME_MPATH | REQ_FAILFAST_TRANSPORT)) { if (nvme_is_path_error(nvme_req(req)->status) || blk_queue_dying(req->q)) - return FAILOVER; + return (req->cmd_flags & REQ_NVME_MPATH) ? + FAILOVER : FAILUP; } else { if (blk_queue_dying(req->q)) return COMPLETE; @@ -336,6 +338,12 @@ static inline void nvme_end_req(struct request *req) blk_mq_end_request(req, status); }
+static inline void nvme_failup_req(struct request *req) +{ + nvme_req(req)->status = NVME_SC_HOST_PATH_ERROR; + nvme_end_req(req); +} + void nvme_complete_rq(struct request *req) { trace_nvme_complete_rq(req); @@ -354,6 +362,9 @@ void nvme_complete_rq(struct request *req) case FAILOVER: nvme_failover_req(req); return; + case FAILUP: + nvme_failup_req(req); + return; } } EXPORT_SYMBOL_GPL(nvme_complete_rq);
-- https://gitlab.com/cki-project/kernel-ark/-/merge_requests/1024
From: Mike Snitzer snitzer@redhat.com
nvme: decouple basic ANA log page re-read support from native multipathing
BZ: 1948690 Upstream Status: RHEL-only
This commit offers a more refined version of this rhel-8.git commit: b904f4b8e0f90 [nvme] nvme: decouple basic ANA log page re-read support from native multipathing
Whether or not ANA is present is a choice of the target implementation; the host (and whether it supports multipathing) has _zero_ influence on this. If the target declares a path as 'inaccessible' the path _is_ inaccessible to the host. As such, ANA support should be functional even if native multipathing is not.
Introduce ability to always re-read ANA log page as required due to ANA error and make current ANA state available via sysfs -- even if native multipathing is disabled on the host (e.g. nvme_core.multipath=N). This is achieved by factoring out nvme_update_ana() and calling it in nvme_complete_rq() for all FAILOVER requests.
This affords userspace access to the current ANA state independent of which layer might be doing multipathing. This makes 'nvme list-subsys' show ANA state for all NVMe subsystems with multiple controllers. It also allows userspace multipath-tools to rely on the NVMe driver for ANA support while dm-multipath takes care of multipathing.
And as always, if embedded NVMe users do not want any performance overhead associated with ANA or native NVMe multipathing they can disable CONFIG_NVME_MULTIPATH.
Signed-off-by: Mike Snitzer snitzer@redhat.com
diff a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -340,6 +340,8 @@ static inline void nvme_end_req(struct request *req)
static inline void nvme_failup_req(struct request *req) { + nvme_update_ana(req); + nvme_req(req)->status = NVME_SC_HOST_PATH_ERROR; nvme_end_req(req); } diff a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -65,13 +65,10 @@ void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns, } }
-void nvme_failover_req(struct request *req) +void nvme_update_ana(struct request *req) { struct nvme_ns *ns = req->q->queuedata; u16 status = nvme_req(req)->status & 0x7ff; - unsigned long flags; - - nvme_mpath_clear_current_path(ns);
/* * If we got back an ANA error, we know the controller is alive but not @@ -82,6 +79,15 @@ void nvme_failover_req(struct request *req) set_bit(NVME_NS_ANA_PENDING, &ns->flags); queue_work(nvme_wq, &ns->ctrl->ana_work); } +} + +void nvme_failover_req(struct request *req) +{ + struct nvme_ns *ns = req->q->queuedata; + unsigned long flags; + + nvme_mpath_clear_current_path(ns); + nvme_update_ana(req);
spin_lock_irqsave(&ns->head->requeue_lock, flags); blk_steal_bios(&ns->head->requeue_list, req); diff a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -664,6 +664,7 @@ void nvme_mpath_start_freeze(struct nvme_subsystem *subsys); void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns, struct nvme_ctrl *ctrl, int *flags); void nvme_failover_req(struct request *req); +void nvme_update_ana(struct request *req); 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 *ns, struct nvme_id_ns *id); @@ -714,6 +715,9 @@ static inline void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns, static inline void nvme_failover_req(struct request *req) { } +static inline void nvme_update_ana(struct request *req) +{ +} static inline void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl) { }
-- https://gitlab.com/cki-project/kernel-ark/-/merge_requests/1024
From: Mike Snitzer snitzer@redhat.com
nvme: multipath: Change default of kernel NVMe multipath to be disabled
BZ: 1948690 Upstream Status: RHEL-only
Signed-off-by: Mike Snitzer snitzer@redhat.com
rhel-8.git commit 8be4b84f8e35dc6e5453b72fe5e60acef795a299 Author: Ewan Milne emilne@redhat.com Date: Fri Mar 22 17:33:52 2019 -0400
[nvme] nvme: multipath: Change default of kernel NVMe multipath to be disabled
Message-id: 20190322173354.8197-20-emilne@redhat.com Patchwork-id: 247393 O-Subject: [RHEL8.1 PATCH 19/21] nvme: multipath: Change default of kernel NVMe multipath to be disabled Bugzilla: 1690940 RH-Acked-by: Tony Camuso tcamuso@redhat.com RH-Acked-by: Mike Snitzer snitzer@redhat.com
Now that CONFIG_NVME_MULTIPATH is enabled, make the default behavior of the kernel to be "disabled" for compatibility with earlier RHEL8.
RHEL-only
Signed-off-by: Ewan D. Milne emilne@redhat.com Signed-off-by: Herton R. Krzesinski herton@redhat.com
diff a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -8,7 +8,11 @@ #include <trace/events/block.h> #include "nvme.h"
+#ifdef CONFIG_RHEL_DIFFERENCES +static bool multipath = false; +#else static bool multipath = true; +#endif module_param(multipath, bool, 0444); MODULE_PARM_DESC(multipath, "turn on native support for multiple controllers per subsystem");
-- https://gitlab.com/cki-project/kernel-ark/-/merge_requests/1024
From: Mike Snitzer on gitlab.com https://gitlab.com/cki-project/kernel-ark/-/merge_requests/1024#note_5562753...
I've revalidated that Christoph Hellwig has no interest in taking these changes: https://listman.redhat.com/archives/dm-devel/2021-April/msg00167.html https://listman.redhat.com/archives/dm-devel/2021-April/msg00167.html
And responded: https://listman.redhat.com/archives/dm-devel/2021-April/msg00169.html https://listman.redhat.com/archives/dm-devel/2021-April/msg00170.html
These changes are being rejected for ideological/political reasons and not technical ones -- at least I'm not hearing a technical argument.
I've also updated this MR so that the changes reflect the latest I proposed for upstream inclusion. These changes are even more minimalist.
@gtiwari1 and @e-milne please review one last time, thanks!
From: Prarit Bhargava on gitlab.com https://gitlab.com/cki-project/kernel-ark/-/merge_requests/1024#note_5570237...
Based on upstream's refusal to take this changeset I'm acking.
From: Prarit Bhargava on gitlab.com https://gitlab.com/cki-project/kernel-ark/-/merge_requests/1024#note_5570240...
@e-milne ? @gtiwari1 ?
From: Gopal Tiwari on gitlab.com https://gitlab.com/cki-project/kernel-ark/-/merge_requests/1024#note_5575086...
Acked-by: Gopal Tiwari gtiwari@redhat.com
From: Mike Snitzer on gitlab.com https://gitlab.com/cki-project/kernel-ark/-/merge_requests/1024#note_5628158...
@jmflinuxtx please provide an update on what you intend to do with this MR.
From: Justin Forbes on gitlab.com https://gitlab.com/cki-project/kernel-ark/-/merge_requests/1024#note_5628247...
While I am not particularly happy about it, I understand the situation. I said it could be merged when it gets the acks, as the code is RHEL only, and the patch will be dropped from stable Fedora releases. I thought @ptalbert was going to merge it at some point this week.
kernel@lists.fedoraproject.org