Commit 65fb1b0d authored by Jens Axboe's avatar Jens Axboe
Browse files

Merge tag 'nvme-5.12-2021-02-11' of git://git.infradead.org/nvme into for-5.12/drivers

Pull NVMe updates from Christoph:

"nvme updates for 5.12:

 - fix multipath handling of ->queue_rq errors (Chao Leng)
 - nvmet cleanups (Chaitanya Kulkarni)
 - add a quirk for buggy Amazon controller (Filippo Sironi)
 - avoid devm allocations in nvme-hwmon that don't interact well with
   fabrics (Hannes Reinecke)
 - sysfs cleanups (Jiapeng Chong)
 - fix nr_zones for multipath (Keith Busch)
 - nvme-tcp crash fix for no-data commands (Sagi Grimberg)
 - nvmet-tcp fixes (Sagi Grimberg)
 - add a missing __rcu annotation (me)"

* tag 'nvme-5.12-2021-02-11' of git://git.infradead.org/nvme: (22 commits)
  nvme-tcp: fix crash triggered with a dataless request submission
  nvme: add 48-bit DMA address quirk for Amazon NVMe controllers
  nvme-hwmon: rework to avoid devm allocation
  nvmet: remove else at the end of the function
  nvmet: add nvmet_req_subsys() helper
  nvmet: use min of device_path and disk len
  nvmet: use invalid cmd opcode helper
  nvmet: use invalid cmd opcode helper
  nvmet: add helper to report invalid opcode
  nvmet: remove extra variable in id-ns handler
  nvmet: make nvmet_find_namespace() req based
  nvmet: return uniform error for invalid ns
  nvmet: set status to 0 in case for invalid nsid
  nvmet-fc: add a missing __rcu annotation to nvmet_fc_tgt_assoc.queues
  nvme-multipath: set nr_zones for zoned namespaces
  nvmet-tcp: fix potential race of tcp socket closing accept_work
  nvmet-tcp: fix receive data digest calculation for multiple h2cdata PDUs
  nvme-rdma: handle nvme_rdma_post_send failures better
  nvme-fabrics: avoid double completions in nvmf_fail_nonready_command
  nvme: introduce a nvme_host_path_error helper
  ...
parents 59788683 e11e5116
Loading
Loading
Loading
Loading
+21 −5
Original line number Diff line number Diff line
@@ -355,6 +355,21 @@ void nvme_complete_rq(struct request *req)
}
EXPORT_SYMBOL_GPL(nvme_complete_rq);

/*
 * Called to unwind from ->queue_rq on a failed command submission so that the
 * multipathing code gets called to potentially failover to another path.
 * The caller needs to unwind all transport specific resource allocations and
 * must return propagate the return value.
 */
blk_status_t nvme_host_path_error(struct request *req)
{
	nvme_req(req)->status = NVME_SC_HOST_PATH_ERROR;
	blk_mq_set_request_complete(req);
	nvme_complete_rq(req);
	return BLK_STS_OK;
}
EXPORT_SYMBOL_GPL(nvme_host_path_error);

bool nvme_cancel_request(struct request *req, void *data, bool reserved)
{
	dev_dbg_ratelimited(((struct nvme_ctrl *) data)->device,
@@ -2848,7 +2863,7 @@ static ssize_t nvme_subsys_show_nqn(struct device *dev,
	struct nvme_subsystem *subsys =
		container_of(dev, struct nvme_subsystem, dev);

	return snprintf(buf, PAGE_SIZE, "%s\n", subsys->subnqn);
	return sysfs_emit(buf, "%s\n", subsys->subnqn);
}
static SUBSYS_ATTR_RO(subsysnqn, S_IRUGO, nvme_subsys_show_nqn);

@@ -3541,7 +3556,7 @@ static ssize_t nvme_sysfs_show_transport(struct device *dev,
{
	struct nvme_ctrl *ctrl = dev_get_drvdata(dev);

	return snprintf(buf, PAGE_SIZE, "%s\n", ctrl->ops->name);
	return sysfs_emit(buf, "%s\n", ctrl->ops->name);
}
static DEVICE_ATTR(transport, S_IRUGO, nvme_sysfs_show_transport, NULL);

@@ -3575,7 +3590,7 @@ static ssize_t nvme_sysfs_show_subsysnqn(struct device *dev,
{
	struct nvme_ctrl *ctrl = dev_get_drvdata(dev);

	return snprintf(buf, PAGE_SIZE, "%s\n", ctrl->subsys->subnqn);
	return sysfs_emit(buf, "%s\n", ctrl->subsys->subnqn);
}
static DEVICE_ATTR(subsysnqn, S_IRUGO, nvme_sysfs_show_subsysnqn, NULL);

@@ -3585,7 +3600,7 @@ static ssize_t nvme_sysfs_show_hostnqn(struct device *dev,
{
	struct nvme_ctrl *ctrl = dev_get_drvdata(dev);

	return snprintf(buf, PAGE_SIZE, "%s\n", ctrl->opts->host->nqn);
	return sysfs_emit(buf, "%s\n", ctrl->opts->host->nqn);
}
static DEVICE_ATTR(hostnqn, S_IRUGO, nvme_sysfs_show_hostnqn, NULL);

@@ -3595,7 +3610,7 @@ static ssize_t nvme_sysfs_show_hostid(struct device *dev,
{
	struct nvme_ctrl *ctrl = dev_get_drvdata(dev);

	return snprintf(buf, PAGE_SIZE, "%pU\n", &ctrl->opts->host->id);
	return sysfs_emit(buf, "%pU\n", &ctrl->opts->host->id);
}
static DEVICE_ATTR(hostid, S_IRUGO, nvme_sysfs_show_hostid, NULL);

@@ -4456,6 +4471,7 @@ EXPORT_SYMBOL_GPL(nvme_start_ctrl);

void nvme_uninit_ctrl(struct nvme_ctrl *ctrl)
{
	nvme_hwmon_exit(ctrl);
	nvme_fault_inject_fini(&ctrl->fault_inject);
	dev_pm_qos_hide_latency_tolerance(ctrl->device);
	cdev_device_del(&ctrl->cdev, ctrl->device);
+1 −5
Original line number Diff line number Diff line
@@ -552,11 +552,7 @@ blk_status_t nvmf_fail_nonready_command(struct nvme_ctrl *ctrl,
	    !test_bit(NVME_CTRL_FAILFAST_EXPIRED, &ctrl->flags) &&
	    !blk_noretry_request(rq) && !(rq->cmd_flags & REQ_NVME_MPATH))
		return BLK_STS_RESOURCE;

	nvme_req(rq)->status = NVME_SC_HOST_PATH_ERROR;
	blk_mq_start_request(rq);
	nvme_complete_rq(rq);
	return BLK_STS_OK;
	return nvme_host_path_error(rq);
}
EXPORT_SYMBOL_GPL(nvmf_fail_nonready_command);

+21 −10
Original line number Diff line number Diff line
@@ -223,12 +223,12 @@ static const struct hwmon_chip_info nvme_hwmon_chip_info = {

int nvme_hwmon_init(struct nvme_ctrl *ctrl)
{
	struct device *dev = ctrl->dev;
	struct device *dev = ctrl->device;
	struct nvme_hwmon_data *data;
	struct device *hwmon;
	int err;

	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
	data = kzalloc(sizeof(*data), GFP_KERNEL);
	if (!data)
		return 0;

@@ -237,19 +237,30 @@ int nvme_hwmon_init(struct nvme_ctrl *ctrl)

	err = nvme_hwmon_get_smart_log(data);
	if (err) {
		dev_warn(ctrl->device,
			"Failed to read smart log (error %d)\n", err);
		devm_kfree(dev, data);
		dev_warn(dev, "Failed to read smart log (error %d)\n", err);
		kfree(data);
		return err;
	}

	hwmon = devm_hwmon_device_register_with_info(dev, "nvme", data,
						     &nvme_hwmon_chip_info,
	hwmon = hwmon_device_register_with_info(dev, "nvme",
						data, &nvme_hwmon_chip_info,
						NULL);
	if (IS_ERR(hwmon)) {
		dev_warn(dev, "Failed to instantiate hwmon device\n");
		devm_kfree(dev, data);
		kfree(data);
	}

	ctrl->hwmon_device = hwmon;
	return 0;
}

void nvme_hwmon_exit(struct nvme_ctrl *ctrl)
{
	if (ctrl->hwmon_device) {
		struct nvme_hwmon_data *data =
			dev_get_drvdata(ctrl->hwmon_device);

		hwmon_device_unregister(ctrl->hwmon_device);
		ctrl->hwmon_device = NULL;
		kfree(data);
	}
}
+4 −0
Original line number Diff line number Diff line
@@ -677,6 +677,10 @@ void nvme_mpath_add_disk(struct nvme_ns *ns, struct nvme_id_ns *id)
	if (blk_queue_stable_writes(ns->queue) && ns->head->disk)
		blk_queue_flag_set(QUEUE_FLAG_STABLE_WRITES,
				   ns->head->disk->queue);
#ifdef CONFIG_BLK_DEV_ZONED
	if (blk_queue_is_zoned(ns->queue) && ns->head->disk)
		ns->head->disk->queue->nr_zones = ns->queue->nr_zones;
#endif
}

void nvme_mpath_remove_disk(struct nvme_ns_head *head)
+15 −0
Original line number Diff line number Diff line
@@ -144,6 +144,12 @@ enum nvme_quirks {
	 * NVMe 1.3 compliance.
	 */
	NVME_QUIRK_NO_NS_DESC_LIST		= (1 << 15),

	/*
	 * The controller does not properly handle DMA addresses over
	 * 48 bits.
	 */
	NVME_QUIRK_DMA_ADDRESS_BITS_48		= (1 << 16),
};

/*
@@ -246,6 +252,9 @@ struct nvme_ctrl {
	struct rw_semaphore namespaces_rwsem;
	struct device ctrl_device;
	struct device *device;	/* char device */
#ifdef CONFIG_NVME_HWMON
	struct device *hwmon_device;
#endif
	struct cdev cdev;
	struct work_struct reset_work;
	struct work_struct delete_work;
@@ -575,6 +584,7 @@ static inline bool nvme_is_aen_req(u16 qid, __u16 command_id)
}

void nvme_complete_rq(struct request *req);
blk_status_t nvme_host_path_error(struct request *req);
bool nvme_cancel_request(struct request *req, void *data, bool reserved);
void nvme_cancel_tagset(struct nvme_ctrl *ctrl);
void nvme_cancel_admin_tagset(struct nvme_ctrl *ctrl);
@@ -811,11 +821,16 @@ static inline struct nvme_ns *nvme_get_ns_from_dev(struct device *dev)

#ifdef CONFIG_NVME_HWMON
int nvme_hwmon_init(struct nvme_ctrl *ctrl);
void nvme_hwmon_exit(struct nvme_ctrl *ctrl);
#else
static inline int nvme_hwmon_init(struct nvme_ctrl *ctrl)
{
	return 0;
}

static inline void nvme_hwmon_exit(struct nvme_ctrl *ctrl)
{
}
#endif

u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
Loading