Commit 8f5914bc authored by Jens Axboe's avatar Jens Axboe
Browse files

Merge branch 'nvme-5.4' of git://git.infradead.org/nvme into for-5.4/block

Pull NVMe changes from Sagi:

"The nvme updates include:
 - ana log parse fix from Anton
 - nvme quirks support for Apple devices from Ben
 - fix missing bio completion tracing for multipath stack devices from
   Hannes and Mikhail
 - IP TOS settings for nvme rdma and tcp transports from Israel
 - rq_dma_dir cleanups from Israel
 - tracing for Get LBA Status command from Minwoo
 - Some nvme-tcp cleanups from Minwoo, Potnuri and Myself
 - Some consolidation between the fabrics transports for handling the CAP
   register
 - reset race with ns scanning fix for fabrics (move fabrics commands to
   a dedicated request queue with a different lifetime from the admin
   request queue)."

* 'nvme-5.4' of git://git.infradead.org/nvme: (30 commits)
  nvme-rdma: Use rq_dma_dir macro
  nvme-fc: Use rq_dma_dir macro
  nvme-pci: Tidy up nvme_unmap_data
  nvme: make fabrics command run on a separate request queue
  nvme-pci: Support shared tags across queues for Apple 2018 controllers
  nvme-pci: Add support for Apple 2018+ models
  nvme-pci: Add support for variable IO SQ element size
  nvme-pci: Pass the queue to SQ_SIZE/CQ_SIZE macros
  nvme: trace bio completion
  nvme-multipath: fix ana log nsid lookup when nsid is not found
  nvmet-tcp: Add TOS for tcp transport
  nvme-tcp: Add TOS for tcp transport
  nvme-tcp: Use struct nvme_ctrl directly
  nvme-rdma: Add TOS for rdma transport
  nvme-fabrics: Add type of service (TOS) configuration
  nvmet-tcp: fix possible memory leak
  nvmet-tcp: fix possible NULL deref
  nvmet: trace: parse Get LBA Status command in detail
  nvme: trace: parse Get LBA Status command in detail
  nvme: trace: support for Get LBA Status opcode parsed
  ...
parents 3a8e9ac8 bc31c1ee
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ config NVME_TCP
	depends on INET
	depends on BLK_DEV_NVME
	select NVME_FABRICS
	select CRYPTO_CRC32C
	help
	  This provides support for the NVMe over Fabrics protocol using
	  the TCP transport.  This allows you to use remote block devices
+20 −17
Original line number Diff line number Diff line
@@ -22,12 +22,12 @@
#include <linux/pm_qos.h>
#include <asm/unaligned.h>

#define CREATE_TRACE_POINTS
#include "trace.h"

#include "nvme.h"
#include "fabrics.h"

#define CREATE_TRACE_POINTS
#include "trace.h"

#define NVME_MINORS		(1U << MINORBITS)

unsigned int admin_timeout = 60;
@@ -279,6 +279,8 @@ void nvme_complete_rq(struct request *req)
			return;
		}
	}

	nvme_trace_bio_complete(req, status);
	blk_mq_end_request(req, status);
}
EXPORT_SYMBOL_GPL(nvme_complete_rq);
@@ -1950,7 +1952,7 @@ static int nvme_wait_ready(struct nvme_ctrl *ctrl, u64 cap, bool enabled)
 * bits', but doing so may cause the device to complete commands to the
 * admin queue ... and we don't know what memory that might be pointing at!
 */
int nvme_disable_ctrl(struct nvme_ctrl *ctrl, u64 cap)
int nvme_disable_ctrl(struct nvme_ctrl *ctrl)
{
	int ret;

@@ -1964,20 +1966,27 @@ int nvme_disable_ctrl(struct nvme_ctrl *ctrl, u64 cap)
	if (ctrl->quirks & NVME_QUIRK_DELAY_BEFORE_CHK_RDY)
		msleep(NVME_QUIRK_DELAY_AMOUNT);

	return nvme_wait_ready(ctrl, cap, false);
	return nvme_wait_ready(ctrl, ctrl->cap, false);
}
EXPORT_SYMBOL_GPL(nvme_disable_ctrl);

int nvme_enable_ctrl(struct nvme_ctrl *ctrl, u64 cap)
int nvme_enable_ctrl(struct nvme_ctrl *ctrl)
{
	/*
	 * Default to a 4K page size, with the intention to update this
	 * path in the future to accomodate architectures with differing
	 * kernel and IO page sizes.
	 */
	unsigned dev_page_min = NVME_CAP_MPSMIN(cap) + 12, page_shift = 12;
	unsigned dev_page_min, page_shift = 12;
	int ret;

	ret = ctrl->ops->reg_read64(ctrl, NVME_REG_CAP, &ctrl->cap);
	if (ret) {
		dev_err(ctrl->device, "Reading CAP failed (%d)\n", ret);
		return ret;
	}
	dev_page_min = NVME_CAP_MPSMIN(ctrl->cap) + 12;

	if (page_shift < dev_page_min) {
		dev_err(ctrl->device,
			"Minimum device page size %u too large for host (%u)\n",
@@ -1996,7 +2005,7 @@ int nvme_enable_ctrl(struct nvme_ctrl *ctrl, u64 cap)
	ret = ctrl->ops->reg_write32(ctrl, NVME_REG_CC, ctrl->ctrl_config);
	if (ret)
		return ret;
	return nvme_wait_ready(ctrl, cap, true);
	return nvme_wait_ready(ctrl, ctrl->cap, true);
}
EXPORT_SYMBOL_GPL(nvme_enable_ctrl);

@@ -2562,7 +2571,6 @@ static int nvme_get_effects_log(struct nvme_ctrl *ctrl)
int nvme_init_identify(struct nvme_ctrl *ctrl)
{
	struct nvme_id_ctrl *id;
	u64 cap;
	int ret, page_shift;
	u32 max_hw_sectors;
	bool prev_apst_enabled;
@@ -2572,16 +2580,11 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
		dev_err(ctrl->device, "Reading VS failed (%d)\n", ret);
		return ret;
	}

	ret = ctrl->ops->reg_read64(ctrl, NVME_REG_CAP, &cap);
	if (ret) {
		dev_err(ctrl->device, "Reading CAP failed (%d)\n", ret);
		return ret;
	}
	page_shift = NVME_CAP_MPSMIN(cap) + 12;
	page_shift = NVME_CAP_MPSMIN(ctrl->cap) + 12;
	ctrl->sqsize = min_t(int, NVME_CAP_MQES(ctrl->cap), ctrl->sqsize);

	if (ctrl->vs >= NVME_VS(1, 1, 0))
		ctrl->subsystem = NVME_CAP_NSSRC(cap);
		ctrl->subsystem = NVME_CAP_NSSRC(ctrl->cap);

	ret = nvme_identify_ctrl(ctrl, &id);
	if (ret) {
+22 −4
Original line number Diff line number Diff line
@@ -150,7 +150,7 @@ int nvmf_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val)
	cmd.prop_get.fctype = nvme_fabrics_type_property_get;
	cmd.prop_get.offset = cpu_to_le32(off);

	ret = __nvme_submit_sync_cmd(ctrl->admin_q, &cmd, &res, NULL, 0, 0,
	ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, &res, NULL, 0, 0,
			NVME_QID_ANY, 0, 0, false);

	if (ret >= 0)
@@ -197,7 +197,7 @@ int nvmf_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val)
	cmd.prop_get.attrib = 1;
	cmd.prop_get.offset = cpu_to_le32(off);

	ret = __nvme_submit_sync_cmd(ctrl->admin_q, &cmd, &res, NULL, 0, 0,
	ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, &res, NULL, 0, 0,
			NVME_QID_ANY, 0, 0, false);

	if (ret >= 0)
@@ -243,7 +243,7 @@ int nvmf_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val)
	cmd.prop_set.offset = cpu_to_le32(off);
	cmd.prop_set.value = cpu_to_le64(val);

	ret = __nvme_submit_sync_cmd(ctrl->admin_q, &cmd, NULL, NULL, 0, 0,
	ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, NULL, NULL, 0, 0,
			NVME_QID_ANY, 0, 0, false);
	if (unlikely(ret))
		dev_err(ctrl->device,
@@ -396,7 +396,7 @@ int nvmf_connect_admin_queue(struct nvme_ctrl *ctrl)
	strncpy(data->subsysnqn, ctrl->opts->subsysnqn, NVMF_NQN_SIZE);
	strncpy(data->hostnqn, ctrl->opts->host->nqn, NVMF_NQN_SIZE);

	ret = __nvme_submit_sync_cmd(ctrl->admin_q, &cmd, &res,
	ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, &res,
			data, sizeof(*data), 0, NVME_QID_ANY, 1,
			BLK_MQ_REQ_RESERVED | BLK_MQ_REQ_NOWAIT, false);
	if (ret) {
@@ -611,6 +611,7 @@ static const match_table_t opt_tokens = {
	{ NVMF_OPT_DATA_DIGEST,		"data_digest"		},
	{ NVMF_OPT_NR_WRITE_QUEUES,	"nr_write_queues=%d"	},
	{ NVMF_OPT_NR_POLL_QUEUES,	"nr_poll_queues=%d"	},
	{ NVMF_OPT_TOS,			"tos=%d"		},
	{ NVMF_OPT_ERR,			NULL			}
};

@@ -632,6 +633,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
	opts->duplicate_connect = false;
	opts->hdr_digest = false;
	opts->data_digest = false;
	opts->tos = -1; /* < 0 == use transport default */

	options = o = kstrdup(buf, GFP_KERNEL);
	if (!options)
@@ -856,6 +858,22 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
			}
			opts->nr_poll_queues = token;
			break;
		case NVMF_OPT_TOS:
			if (match_int(args, &token)) {
				ret = -EINVAL;
				goto out;
			}
			if (token < 0) {
				pr_err("Invalid type of service %d\n", token);
				ret = -EINVAL;
				goto out;
			}
			if (token > 255) {
				pr_warn("Clamping type of service to 255\n");
				token = 255;
			}
			opts->tos = token;
			break;
		default:
			pr_warn("unknown parameter or missing value '%s' in ctrl creation request\n",
				p);
+3 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ enum {
	NVMF_OPT_DATA_DIGEST	= 1 << 16,
	NVMF_OPT_NR_WRITE_QUEUES = 1 << 17,
	NVMF_OPT_NR_POLL_QUEUES = 1 << 18,
	NVMF_OPT_TOS		= 1 << 19,
};

/**
@@ -87,6 +88,7 @@ enum {
 * @data_digest: generate/verify data digest (TCP)
 * @nr_write_queues: number of queues for write I/O
 * @nr_poll_queues: number of queues for polling I/O
 * @tos: type of service
 */
struct nvmf_ctrl_options {
	unsigned		mask;
@@ -108,6 +110,7 @@ struct nvmf_ctrl_options {
	bool			data_digest;
	unsigned int		nr_write_queues;
	unsigned int		nr_poll_queues;
	int			tos;
};

/*
+15 −19
Original line number Diff line number Diff line
@@ -2006,6 +2006,7 @@ nvme_fc_ctrl_free(struct kref *ref)

	blk_mq_unquiesce_queue(ctrl->ctrl.admin_q);
	blk_cleanup_queue(ctrl->ctrl.admin_q);
	blk_cleanup_queue(ctrl->ctrl.fabrics_q);
	blk_mq_free_tag_set(&ctrl->admin_tag_set);

	kfree(ctrl->queues);
@@ -2107,7 +2108,6 @@ nvme_fc_map_data(struct nvme_fc_ctrl *ctrl, struct request *rq,
		struct nvme_fc_fcp_op *op)
{
	struct nvmefc_fcp_req *freq = &op->fcp_req;
	enum dma_data_direction dir;
	int ret;

	freq->sg_cnt = 0;
@@ -2124,9 +2124,8 @@ nvme_fc_map_data(struct nvme_fc_ctrl *ctrl, struct request *rq,

	op->nents = blk_rq_map_sg(rq->q, rq, freq->sg_table.sgl);
	WARN_ON(op->nents > blk_rq_nr_phys_segments(rq));
	dir = (rq_data_dir(rq) == WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
	freq->sg_cnt = fc_dma_map_sg(ctrl->lport->dev, freq->sg_table.sgl,
				op->nents, dir);
				op->nents, rq_dma_dir(rq));
	if (unlikely(freq->sg_cnt <= 0)) {
		sg_free_table_chained(&freq->sg_table, SG_CHUNK_SIZE);
		freq->sg_cnt = 0;
@@ -2149,8 +2148,7 @@ nvme_fc_unmap_data(struct nvme_fc_ctrl *ctrl, struct request *rq,
		return;

	fc_dma_unmap_sg(ctrl->lport->dev, freq->sg_table.sgl, op->nents,
				((rq_data_dir(rq) == WRITE) ?
					DMA_TO_DEVICE : DMA_FROM_DEVICE));
			rq_dma_dir(rq));

	nvme_cleanup_cmd(rq);

@@ -2633,8 +2631,6 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)
	if (ret)
		goto out_delete_hw_queue;

	blk_mq_unquiesce_queue(ctrl->ctrl.admin_q);

	ret = nvmf_connect_admin_queue(&ctrl->ctrl);
	if (ret)
		goto out_disconnect_admin_queue;
@@ -2648,23 +2644,15 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)
	 * prior connection values
	 */

	ret = nvmf_reg_read64(&ctrl->ctrl, NVME_REG_CAP, &ctrl->ctrl.cap);
	if (ret) {
		dev_err(ctrl->ctrl.device,
			"prop_get NVME_REG_CAP failed\n");
		goto out_disconnect_admin_queue;
	}

	ctrl->ctrl.sqsize =
		min_t(int, NVME_CAP_MQES(ctrl->ctrl.cap), ctrl->ctrl.sqsize);

	ret = nvme_enable_ctrl(&ctrl->ctrl, ctrl->ctrl.cap);
	ret = nvme_enable_ctrl(&ctrl->ctrl);
	if (ret)
		goto out_disconnect_admin_queue;

	ctrl->ctrl.max_hw_sectors =
		(ctrl->lport->ops->max_sgl_segments - 1) << (PAGE_SHIFT - 9);

	blk_mq_unquiesce_queue(ctrl->ctrl.admin_q);

	ret = nvme_init_identify(&ctrl->ctrl);
	if (ret)
		goto out_disconnect_admin_queue;
@@ -3111,10 +3099,16 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
		goto out_free_queues;
	ctrl->ctrl.admin_tagset = &ctrl->admin_tag_set;

	ctrl->ctrl.fabrics_q = blk_mq_init_queue(&ctrl->admin_tag_set);
	if (IS_ERR(ctrl->ctrl.fabrics_q)) {
		ret = PTR_ERR(ctrl->ctrl.fabrics_q);
		goto out_free_admin_tag_set;
	}

	ctrl->ctrl.admin_q = blk_mq_init_queue(&ctrl->admin_tag_set);
	if (IS_ERR(ctrl->ctrl.admin_q)) {
		ret = PTR_ERR(ctrl->ctrl.admin_q);
		goto out_free_admin_tag_set;
		goto out_cleanup_fabrics_q;
	}

	/*
@@ -3186,6 +3180,8 @@ fail_ctrl:

out_cleanup_admin_q:
	blk_cleanup_queue(ctrl->ctrl.admin_q);
out_cleanup_fabrics_q:
	blk_cleanup_queue(ctrl->ctrl.fabrics_q);
out_free_admin_tag_set:
	blk_mq_free_tag_set(&ctrl->admin_tag_set);
out_free_queues:
Loading