Skip to content

Commit f46d273

Browse files
author
Christoph Hellwig
committed
nvme: fix atomic write size validation
Don't mix the namespace and controller values, and validate the per-controller limit when probing the controller. This avoid spurious failures for controllers with namespaces that have different namespaces with different logical block sizes, or report the per-namespace values only for some namespaces. It also fixes a missing queue_limits_cancel_update in an error path by removing that error path. Fixes: 8695f06 ("nvme: all namespaces in a subsystem must adhere to a common atomic write size") Reported-by: Yi Zhang <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Luis Chamberlain <[email protected]> Reviewed-by: John Garry <[email protected]> Tested-by: Yi Zhang <[email protected]>
1 parent b2e607f commit f46d273

File tree

2 files changed

+12
-24
lines changed

2 files changed

+12
-24
lines changed

drivers/nvme/host/core.c

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,17 +2041,7 @@ static u32 nvme_configure_atomic_write(struct nvme_ns *ns,
20412041
* no clear language in the specification prohibiting different
20422042
* values for different controllers in the subsystem.
20432043
*/
2044-
atomic_bs = (1 + ns->ctrl->awupf) * bs;
2045-
}
2046-
2047-
if (!ns->ctrl->subsys->atomic_bs) {
2048-
ns->ctrl->subsys->atomic_bs = atomic_bs;
2049-
} else if (ns->ctrl->subsys->atomic_bs != atomic_bs) {
2050-
dev_err_ratelimited(ns->ctrl->device,
2051-
"%s: Inconsistent Atomic Write Size, Namespace will not be added: Subsystem=%d bytes, Controller/Namespace=%d bytes\n",
2052-
ns->disk ? ns->disk->disk_name : "?",
2053-
ns->ctrl->subsys->atomic_bs,
2054-
atomic_bs);
2044+
atomic_bs = (1 + ns->ctrl->subsys->awupf) * bs;
20552045
}
20562046

20572047
lim->atomic_write_hw_max = atomic_bs;
@@ -2386,16 +2376,6 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
23862376
if (!nvme_update_disk_info(ns, id, &lim))
23872377
capacity = 0;
23882378

2389-
/*
2390-
* Validate the max atomic write size fits within the subsystem's
2391-
* atomic write capabilities.
2392-
*/
2393-
if (lim.atomic_write_hw_max > ns->ctrl->subsys->atomic_bs) {
2394-
blk_mq_unfreeze_queue(ns->disk->queue, memflags);
2395-
ret = -ENXIO;
2396-
goto out;
2397-
}
2398-
23992379
nvme_config_discard(ns, &lim);
24002380
if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) &&
24012381
ns->head->ids.csi == NVME_CSI_ZNS)
@@ -3219,6 +3199,7 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
32193199
memcpy(subsys->model, id->mn, sizeof(subsys->model));
32203200
subsys->vendor_id = le16_to_cpu(id->vid);
32213201
subsys->cmic = id->cmic;
3202+
subsys->awupf = le16_to_cpu(id->awupf);
32223203

32233204
/* Versions prior to 1.4 don't necessarily report a valid type */
32243205
if (id->cntrltype == NVME_CTRL_DISC ||
@@ -3556,6 +3537,15 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl)
35563537
if (ret)
35573538
goto out_free;
35583539
}
3540+
3541+
if (le16_to_cpu(id->awupf) != ctrl->subsys->awupf) {
3542+
dev_err_ratelimited(ctrl->device,
3543+
"inconsistent AWUPF, controller not added (%u/%u).\n",
3544+
le16_to_cpu(id->awupf), ctrl->subsys->awupf);
3545+
ret = -EINVAL;
3546+
goto out_free;
3547+
}
3548+
35593549
memcpy(ctrl->subsys->firmware_rev, id->fr,
35603550
sizeof(ctrl->subsys->firmware_rev));
35613551

@@ -3651,7 +3641,6 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl)
36513641
dev_pm_qos_expose_latency_tolerance(ctrl->device);
36523642
else if (!ctrl->apst_enabled && prev_apst_enabled)
36533643
dev_pm_qos_hide_latency_tolerance(ctrl->device);
3654-
ctrl->awupf = le16_to_cpu(id->awupf);
36553644
out_free:
36563645
kfree(id);
36573646
return ret;

drivers/nvme/host/nvme.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,6 @@ struct nvme_ctrl {
410410

411411
enum nvme_ctrl_type cntrltype;
412412
enum nvme_dctype dctype;
413-
u16 awupf; /* 0's based value. */
414413
};
415414

416415
static inline enum nvme_ctrl_state nvme_ctrl_state(struct nvme_ctrl *ctrl)
@@ -443,11 +442,11 @@ struct nvme_subsystem {
443442
u8 cmic;
444443
enum nvme_subsys_type subtype;
445444
u16 vendor_id;
445+
u16 awupf; /* 0's based value. */
446446
struct ida ns_ida;
447447
#ifdef CONFIG_NVME_MULTIPATH
448448
enum nvme_iopolicy iopolicy;
449449
#endif
450-
u32 atomic_bs;
451450
};
452451

453452
/*

0 commit comments

Comments
 (0)