Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c86b8f7b authored by Christoph Hellwig's avatar Christoph Hellwig
Browse files

nvmet: add AEN configuration support



AEN configuration via the 'Get Features' and 'Set Features' admin
command is mandatory, so we should be implemeting handling for it.

Signed-off-by: default avatarHannes Reinecke <hare@suse.com>
[hch: use WRITE_ONCE, check for invalid values]
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarSagi Grimberg <sagi@grimberg.me>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent c16734ea
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -189,7 +189,7 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
	id->ver = cpu_to_le32(ctrl->subsys->ver);

	/* XXX: figure out what to do about RTD3R/RTD3 */
	id->oaes = cpu_to_le32(1 << 8);
	id->oaes = cpu_to_le32(NVMET_AEN_CFG_OPTIONAL);
	id->ctratt = cpu_to_le32(1 << 0);

	id->oacs = 0;
@@ -435,6 +435,16 @@ static void nvmet_execute_set_features(struct nvmet_req *req)
		req->sq->ctrl->kato = DIV_ROUND_UP(val32, 1000);
		nvmet_set_result(req, req->sq->ctrl->kato);
		break;
	case NVME_FEAT_ASYNC_EVENT:
		val32 = le32_to_cpu(req->cmd->common.cdw10[1]);
		if (val32 & ~NVMET_AEN_CFG_ALL) {
			status = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
			break;
		}

		WRITE_ONCE(req->sq->ctrl->aen_enabled, val32);
		nvmet_set_result(req, val32);
		break;
	case NVME_FEAT_HOST_ID:
		status = NVME_SC_CMD_SEQ_ERROR | NVME_SC_DNR;
		break;
@@ -473,9 +483,10 @@ static void nvmet_execute_get_features(struct nvmet_req *req)
		break;
	case NVME_FEAT_WRITE_ATOMIC:
		break;
#endif
	case NVME_FEAT_ASYNC_EVENT:
		nvmet_set_result(req, READ_ONCE(req->sq->ctrl->aen_enabled));
		break;
#endif
	case NVME_FEAT_VOLATILE_WC:
		nvmet_set_result(req, 1);
		break;
+3 −0
Original line number Diff line number Diff line
@@ -174,6 +174,8 @@ static void nvmet_ns_changed(struct nvmet_subsys *subsys, u32 nsid)

	list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) {
		nvmet_add_to_changed_ns_log(ctrl, cpu_to_le32(nsid));
		if (!(READ_ONCE(ctrl->aen_enabled) & NVME_AEN_CFG_NS_ATTR))
			continue;
		nvmet_add_async_event(ctrl, NVME_AER_TYPE_NOTICE,
				NVME_AER_NOTICE_NS_CHANGED,
				NVME_LOG_CHANGED_NS);
@@ -861,6 +863,7 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,

	kref_init(&ctrl->ref);
	ctrl->subsys = subsys;
	WRITE_ONCE(ctrl->aen_enabled, NVMET_AEN_CFG_OPTIONAL);

	ctrl->changed_ns_list = kmalloc_array(NVME_MAX_CHANGED_NAMESPACES,
			sizeof(__le32), GFP_KERNEL);
+16 −0
Original line number Diff line number Diff line
@@ -30,6 +30,21 @@
#define NVMET_ASYNC_EVENTS		4
#define NVMET_ERROR_LOG_SLOTS		128


/*
 * Supported optional AENs:
 */
#define NVMET_AEN_CFG_OPTIONAL \
	NVME_AEN_CFG_NS_ATTR

/*
 * Plus mandatory SMART AENs (we'll never send them, but allow enabling them):
 */
#define NVMET_AEN_CFG_ALL \
	(NVME_SMART_CRIT_SPARE | NVME_SMART_CRIT_TEMPERATURE | \
	 NVME_SMART_CRIT_RELIABILITY | NVME_SMART_CRIT_MEDIA | \
	 NVME_SMART_CRIT_VOLATILE_MEMORY | NVMET_AEN_CFG_OPTIONAL)

/* Helper Macros when NVMe error is NVME_SC_CONNECT_INVALID_PARAM
 * The 16 bit shift is to set IATTR bit to 1, which means offending
 * offset starts in the data section of connect()
@@ -123,6 +138,7 @@ struct nvmet_ctrl {
	u16			cntlid;
	u32			kato;

	u32			aen_enabled;
	struct nvmet_req	*async_event_cmds[NVMET_ASYNC_EVENTS];
	unsigned int		nr_async_event_cmds;
	struct list_head	async_events;