[PATCH] nvmet: parametrize maximum number of namespaces
Hannes Reinecke
hare at suse.de
Tue Feb 22 01:39:20 PST 2022
On 2/22/22 09:54, Aleksandr Dyadyushkin wrote:
> From: Aleksandr Dyadyushkin <alextalker at yandex.ru>
>
> Allow the end user (i.e. the administrator) to set maximum number of
> namespaces (and thus NN and MNAN implicitly) via module loading-time
> parameter, without a need to modify and rebuild source code.
>
> Most of all this can be helpful for mock-up configurations and possibly
> really sparse NSID assignments.
>
> For backwards compatibility, default values are left as is.
>
> While permitted values are choosen as high as possible for the current
> code architecture and standard limitations, it is worth noting that
> allocations at 'nvmet_execute_get_log_page_ana' might yield a failure in
> runtime on systems with high parameter value and low free memory.
>
> Signed-off-by: Aleksandr Dyadyushkin <alextalker at ya.ru>
> ---
> drivers/nvme/target/admin-cmd.c | 6 +++---
> drivers/nvme/target/core.c | 28 +++++++++++++++++++++++++++-
> drivers/nvme/target/nvmet.h | 2 ++
> 3 files changed, 32 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
> index 6fb24746de06..940297233986 100644
> --- a/drivers/nvme/target/admin-cmd.c
> +++ b/drivers/nvme/target/admin-cmd.c
> @@ -278,7 +278,7 @@ static void nvmet_execute_get_log_page_ana(struct nvmet_req *req)
> u16 status;
>
> status = NVME_SC_INTERNAL;
> - desc = kmalloc(struct_size(desc, nsids, NVMET_MAX_NAMESPACES),
> + desc = kmalloc(struct_size(desc, nsids, nvmet_max_namespaces),
> GFP_KERNEL);
> if (!desc)
> goto out;
> @@ -428,8 +428,8 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
> /* no enforcement soft-limit for maxcmd - pick arbitrary high value */
> id->maxcmd = cpu_to_le16(NVMET_MAX_CMD);
>
> - id->nn = cpu_to_le32(NVMET_MAX_NAMESPACES);
> - id->mnan = cpu_to_le32(NVMET_MAX_NAMESPACES);
> + id->nn = cpu_to_le32(nvmet_max_namespaces);
> + id->mnan = cpu_to_le32(nvmet_max_namespaces);
> id->oncs = cpu_to_le16(NVME_CTRL_ONCS_DSM |
> NVME_CTRL_ONCS_WRITE_ZEROES);
>
> diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
> index 5119c687de68..1b925b40074d 100644
> --- a/drivers/nvme/target/core.c
> +++ b/drivers/nvme/target/core.c
> @@ -15,6 +15,32 @@
>
> #include "nvmet.h"
>
> +static int max_namespaces_set(const char *val, const struct kernel_param *kp);
> +static const struct kernel_param_ops max_namespaces_ops = {
> + .set = max_namespaces_set,
> + .get = param_get_uint,
> +};
> +
> +/* Account for 0h NSID */
> +#define NVMET_NSID_MAX (NVME_NSID_ALL - 1)
> +
> +u32 nvmet_max_namespaces = NVMET_MAX_NAMESPACES;
> +module_param_cb(max_namespaces, &max_namespaces_ops, &nvmet_max_namespaces, 0444);
> +MODULE_PARM_DESC(max_namespaces, "Set maximum number of namespaces per subsystem (default: 1024)");
> +
> +static int max_namespaces_set(const char *val, const struct kernel_param *kp) {
> + int ret;
> + u32 n;
> +
> + ret = kstrtouint(val, 10, &n);
> + if (ret != 0)
> + return -EINVAL;
> + if (n == 0 || n >= NVMET_NSID_MAX)
> + return -EINVAL;
> +
> + return param_set_uint(val, kp);
> +}
> +
> struct workqueue_struct *buffered_io_wq;
> struct workqueue_struct *zbd_wq;
> static const struct nvmet_fabrics_ops *nvmet_transports[NVMF_TRTYPE_MAX];
> @@ -562,7 +588,7 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
> goto out_unlock;
>
> ret = -EMFILE;
> - if (subsys->nr_namespaces == NVMET_MAX_NAMESPACES)
> + if (subsys->nr_namespaces == nvmet_max_namespaces)
> goto out_unlock;
>
> ret = nvmet_bdev_ns_enable(ns);
> diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
> index af193423c10b..ed4873963cc3 100644
> --- a/drivers/nvme/target/nvmet.h
> +++ b/drivers/nvme/target/nvmet.h
> @@ -506,6 +506,8 @@ void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type,
> */
> #define NVMET_MAX_NAMESPACES 1024
>
> +extern u32 nvmet_max_namespaces;
> +
> /*
> * 0 is not a valid ANA group ID, so we start numbering at 1.
> *
Please make this a subsystem attribute.
That's precisely why we have configfs :-)
Cheers,
Hannes
--
Dr. Hannes Reinecke Kernel Storage Architect
hare at suse.de +49 911 74053 688
SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg
HRB 36809 (AG Nürnberg), Geschäftsführer: Felix Imendörffer
More information about the Linux-nvme
mailing list