[PATCH 04/13] nvme-multipath: queue-depth support for marginal paths

From: Jesse Taube

Date: Wed Aug 12 2026 - 14:15:53 EST


From: John Meneghini <jmeneghi@xxxxxxxxxx>

Exclude marginal paths from queue-depth io policy. In the case where all
paths are marginal and no optimized or non-optimized path is found, we
fall back and select the best marginal path.

Signed-off-by: Jesse Taube <jtaubepe@xxxxxxxxxx>
Signed-off-by: John Meneghini <jmeneghi@xxxxxxxxxx>
---
V10 -> V11:
- New commit
---
drivers/nvme/host/multipath.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index 02936c580a37..dc34634842be 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -453,7 +453,9 @@ static struct nvme_ns *nvme_round_robin_path(struct nvme_ns_head *head)
static struct nvme_ns *nvme_queue_depth_path(struct nvme_ns_head *head)
{
struct nvme_ns *best_opt = NULL, *best_nonopt = NULL, *ns;
- unsigned int min_depth_opt = UINT_MAX, min_depth_nonopt = UINT_MAX;
+ int min_depth_opt = INT_MAX, min_depth_nonopt = INT_MAX;
+ bool opt_is_marginal = true, nonopt_is_marginal = true, marginal;
+
unsigned int depth;

list_for_each_entry_srcu(ns, &head->list, siblings,
@@ -462,28 +464,40 @@ static struct nvme_ns *nvme_queue_depth_path(struct nvme_ns_head *head)
continue;

depth = atomic_read(&ns->ctrl->nr_active);
+ marginal = nvme_ctrl_is_marginal(ns->ctrl);

switch (ns->ana_state) {
case NVME_ANA_OPTIMIZED:
- if (depth < min_depth_opt) {
+ if (is_best_distance(opt_is_marginal, marginal,
+ min_depth_opt, depth)) {
min_depth_opt = depth;
best_opt = ns;
+ opt_is_marginal = marginal;
}
break;
case NVME_ANA_NONOPTIMIZED:
- if (depth < min_depth_nonopt) {
+ if (is_best_distance(nonopt_is_marginal, marginal,
+ min_depth_nonopt, depth)) {
min_depth_nonopt = depth;
best_nonopt = ns;
+ nonopt_is_marginal = marginal;
}
break;
default:
break;
}

- if (min_depth_opt == 0)
+ if (min_depth_opt == 0 && !opt_is_marginal)
return best_opt;
}

+ /*
+ * Prefer non-marginal non-optimized path
+ * over a marginal optimized path.
+ */
+ if (opt_is_marginal && !nonopt_is_marginal && best_nonopt)
+ return best_nonopt;
+
return best_opt ? best_opt : best_nonopt;
}

--
2.54.0