Commit 0a5a9464 authored by Aurelien Aptel's avatar Aurelien Aptel Committed by Keith Busch
Browse files

nvmet: introduce new mdts configuration entry



Using this port configuration, one will be able to set the Maximum Data
Transfer Size (MDTS) for any controller that will be associated to the
configured port. The default value remains 0 (no limit).

Signed-off-by: default avatarMax Gurtovoy <mgurtovoy@nvidia.com>
Signed-off-by: default avatarAurelien Aptel <aaptel@nvidia.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarKeith Busch <kbusch@kernel.org>
parent 723277b1
Loading
Loading
Loading
Loading
+2 −6
Original line number Diff line number Diff line
@@ -687,12 +687,8 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
	id->cmic = NVME_CTRL_CMIC_MULTI_PORT | NVME_CTRL_CMIC_MULTI_CTRL |
		NVME_CTRL_CMIC_ANA;

	/* Limit MDTS according to transport capability */
	if (ctrl->ops->get_mdts)
		id->mdts = ctrl->ops->get_mdts(ctrl);
	else
		id->mdts = 0;

	/* Limit MDTS according to port config or transport capability */
	id->mdts = nvmet_ctrl_mdts(req);
	id->cntlid = cpu_to_le16(ctrl->cntlid);
	id->ver = cpu_to_le32(ctrl->subsys->ver);

+27 −0
Original line number Diff line number Diff line
@@ -301,6 +301,31 @@ static ssize_t nvmet_param_max_queue_size_store(struct config_item *item,

CONFIGFS_ATTR(nvmet_, param_max_queue_size);

static ssize_t nvmet_param_mdts_show(struct config_item *item, char *page)
{
	struct nvmet_port *port = to_nvmet_port(item);

	return snprintf(page, PAGE_SIZE, "%d\n", port->mdts);
}

static ssize_t nvmet_param_mdts_store(struct config_item *item,
		const char *page, size_t count)
{
	struct nvmet_port *port = to_nvmet_port(item);
	int ret;

	if (nvmet_is_port_enabled(port, __func__))
		return -EACCES;
	ret = kstrtoint(page, 0, &port->mdts);
	if (ret) {
		pr_err("Invalid value '%s' for mdts\n", page);
		return -EINVAL;
	}
	return count;
}

CONFIGFS_ATTR(nvmet_, param_mdts);

#ifdef CONFIG_BLK_DEV_INTEGRITY
static ssize_t nvmet_param_pi_enable_show(struct config_item *item,
		char *page)
@@ -1995,6 +2020,7 @@ static struct configfs_attribute *nvmet_port_attrs[] = {
	&nvmet_attr_addr_tsas,
	&nvmet_attr_param_inline_data_size,
	&nvmet_attr_param_max_queue_size,
	&nvmet_attr_param_mdts,
#ifdef CONFIG_BLK_DEV_INTEGRITY
	&nvmet_attr_param_pi_enable,
#endif
@@ -2053,6 +2079,7 @@ static struct config_group *nvmet_ports_make(struct config_group *group,
	INIT_LIST_HEAD(&port->referrals);
	port->inline_data_size = -1;	/* < 0 == let the transport choose */
	port->max_queue_size = -1;	/* < 0 == let the transport choose */
	port->mdts = -1;		/* < 0 == let the transport choose */

	port->disc_addr.trtype = NVMF_TRTYPE_MAX;
	port->disc_addr.portid = cpu_to_le16(portid);
+8 −0
Original line number Diff line number Diff line
@@ -368,6 +368,14 @@ int nvmet_enable_port(struct nvmet_port *port)
					       NVMET_MIN_QUEUE_SIZE,
					       NVMET_MAX_QUEUE_SIZE);

	/*
	 * If the transport didn't set the mdts properly, then clamp it to the
	 * target limits. Also set default values in case the transport didn't
	 * set it at all.
	 */
	if (port->mdts < 0 || port->mdts > NVMET_MAX_MDTS)
		port->mdts = 0;

	port->enabled = true;
	port->tr_ops = ops;
	return 0;
+13 −0
Original line number Diff line number Diff line
@@ -214,6 +214,7 @@ struct nvmet_port {
	bool				enabled;
	int				inline_data_size;
	int				max_queue_size;
	int				mdts;
	const struct nvmet_fabrics_ops	*tr_ops;
	bool				pi_enable;
};
@@ -672,6 +673,7 @@ void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type,
#define NVMET_MAX_QUEUE_SIZE	1024
#define NVMET_NR_QUEUES		128
#define NVMET_MAX_CMD(ctrl)	(NVME_CAP_MQES(ctrl->cap) + 1)
#define NVMET_MAX_MDTS		255

/*
 * Nice round number that makes a list of nsids fit into a page.
@@ -760,6 +762,17 @@ static inline bool nvmet_is_pci_ctrl(struct nvmet_ctrl *ctrl)
	return ctrl->port->disc_addr.trtype == NVMF_TRTYPE_PCI;
}

/* Limit MDTS according to port config or transport capability */
static inline u8 nvmet_ctrl_mdts(struct nvmet_req *req)
{
	struct nvmet_ctrl *ctrl = req->sq->ctrl;
	u8 mdts = req->port->mdts;

	if (!ctrl->ops->get_mdts)
		return mdts;
	return min_not_zero(ctrl->ops->get_mdts(ctrl), mdts);
}

#ifdef CONFIG_NVME_TARGET_PASSTHRU
void nvmet_passthru_subsys_free(struct nvmet_subsys *subsys);
int nvmet_passthru_ctrl_enable(struct nvmet_subsys *subsys);
+1 −5
Original line number Diff line number Diff line
@@ -69,7 +69,6 @@ bool nvmet_bdev_zns_enable(struct nvmet_ns *ns)
void nvmet_execute_identify_ctrl_zns(struct nvmet_req *req)
{
	u8 zasl = req->sq->ctrl->subsys->zasl;
	struct nvmet_ctrl *ctrl = req->sq->ctrl;
	struct nvme_id_ctrl_zns *id;
	u16 status;

@@ -79,10 +78,7 @@ void nvmet_execute_identify_ctrl_zns(struct nvmet_req *req)
		goto out;
	}

	if (ctrl->ops->get_mdts)
		id->zasl = min_t(u8, ctrl->ops->get_mdts(ctrl), zasl);
	else
		id->zasl = zasl;
	id->zasl = min_not_zero(nvmet_ctrl_mdts(req), zasl);

	status = nvmet_copy_to_sgl(req, 0, id, sizeof(*id));