diff options
| author | Luis Chamberlain <mcgrof@kernel.org> | 2025-04-28 15:34:47 -0700 |
|---|---|---|
| committer | Luis Chamberlain <mcgrof@kernel.org> | 2025-04-28 15:34:47 -0700 |
| commit | 42bbcb07bfd0871e316974b3be276b7198be4b2e (patch) | |
| tree | a5b047fdbac49e77435de78b3554ddb61650c65c | |
| parent | 6060ec8de0b0cbba99813d1ae97d8d5f201850e7 (diff) | |
| download | linux-20250428-pwrite.tar.gz | |
nvme: add nvme_core.debug_large_atomics to force high awun as phys_bs20250428-pwrite
A drive with atomic write support should have awun / nawun defined,
for these drives it should be possible to play with and experiment
safely with large atomics support up to awun / nawun settings if you are
completely ignoring power failure situations. Add support to
experiment with this. The rationale to limit to awun / nawun is
to avoid races with other on flight commands which otherwise
could cause unexpected results.
This also means this debug module parameter feature is not supported
if your drive does not support atomics / awun / nawun. Use a taint
flag in case this debug module parameter is used.
Example usage: nvme_core.debug_large_atomics=16384
Suggested-by: Dan Helmick <dan.helmick@samsung.com>
Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
| -rw-r--r-- | drivers/nvme/host/core.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index e707fc42b9463d..26bfa51f2c0624 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -105,6 +105,17 @@ MODULE_PARM_DESC(disable_pi_offsets, "disable protection information if it has an offset"); /* + * A drive with atomic write support should have awun / nawun defined, for these + * drives it should be possible to play with and experiment safely with large + * atomics up to awun / nawun settings *iff* you are completely ignoring power + * failure situations. The rationale to limit to awun / nawun is to avoid races + * with other on flight commands which otherwise could cause unexpected results. + */ +static unsigned int debug_large_atomics; +module_param(debug_large_atomics, uint, 0644); +MODULE_PARM_DESC(debug_large_atomics, "allow large atomics <= awun or nawun <= mdts"); + +/* * nvme_wq - hosts nvme related works that are not reset or delete * nvme_reset_wq - hosts nvme reset works * nvme_delete_wq - hosts nvme delete works @@ -2008,6 +2019,9 @@ static void nvme_update_atomic_write_disk_info(struct nvme_ns *ns, boundary = (le16_to_cpu(id->nabspf) + 1) * bs; } + if (debug_large_atomics && awun_bs >= debug_large_atomics) + boundary = min(atomic_bs, awun_bs); + if (awun_bs) { atomic_bs = min(atomic_bs, awun_bs); boundary = min(boundary, awun_bs); @@ -2078,6 +2092,19 @@ static bool nvme_update_disk_info(struct nvme_ns *ns, struct nvme_id_ns *id, else atomic_bs = (1 + ns->ctrl->subsys->awupf) * bs; + if (debug_large_atomics && awun_bs >= debug_large_atomics) { + atomic_bs = min(debug_large_atomics, awun_bs); + add_taint(TAINT_TEST, LOCKDEP_STILL_OK); + dev_info(ns->ctrl->device, + "Forcing large atomic: %u (awun_bs: %u awun: %u)\n", + debug_large_atomics, awun_bs, awun); + } else if (debug_large_atomics) { + dev_info(ns->ctrl->device, + "Disired large atomic: %u is smaller than awun. Ignoring. (awun_bs: %u awun: %u)\n", + debug_large_atomics, awun_bs, awun); + debug_large_atomics = 0; + } + nvme_update_atomic_write_disk_info(ns, id, lim, bs, atomic_bs, awun_bs); } @@ -2085,6 +2112,9 @@ static bool nvme_update_disk_info(struct nvme_ns *ns, struct nvme_id_ns *id, if (id->nsfeat & NVME_NS_FEAT_IO_OPT) { /* NPWG = Namespace Preferred Write Granularity */ phys_bs = bs * (1 + le16_to_cpu(id->npwg)); + /* This enables you to experiment with large fs sector sizes */ + if (debug_large_atomics && awun_bs > debug_large_atomics) + phys_bs = min(debug_large_atomics, awun_bs); /* NOWS = Namespace Optimal Write Size */ if (id->nows) io_opt = bs * (1 + le16_to_cpu(id->nows)); |
