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: Hannes Reinecke <hare@suse.com> [hch: use WRITE_ONCE, check for invalid values] Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Sagi Grimberg <sagi@grimberg.me> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
parent
c16734ea98
commit
c86b8f7b41
3 changed files with 33 additions and 3 deletions
|
@ -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;
|
||||
case NVME_FEAT_ASYNC_EVENT:
|
||||
break;
|
||||
#endif
|
||||
case NVME_FEAT_ASYNC_EVENT:
|
||||
nvmet_set_result(req, READ_ONCE(req->sq->ctrl->aen_enabled));
|
||||
break;
|
||||
case NVME_FEAT_VOLATILE_WC:
|
||||
nvmet_set_result(req, 1);
|
||||
break;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue