Re: [PATCH 07/12] nvmet: Add AEN configuration support

2018-05-30 Thread Sagi Grimberg

Looks good,

Reviewed-by: Sagi Grimberg 


[PATCH 07/12] nvmet: Add AEN configuration support

2018-05-30 Thread Christoph Hellwig
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 
[hch: use WRITE_ONCE, check for invalid values]
Signed-off-by: Christoph Hellwig 
---
 drivers/nvme/target/admin-cmd.c | 15 +--
 drivers/nvme/target/core.c  |  3 +++
 drivers/nvme/target/nvmet.h | 16 
 3 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
index 453d76db1647..4e269a8c8dbe 100644
--- a/drivers/nvme/target/admin-cmd.c
+++ b/drivers/nvme/target/admin-cmd.c
@@ -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;
@@ -441,6 +441,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;
@@ -479,9 +489,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;
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 99fcff757608..b2da65aec8b7 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -168,6 +168,8 @@ static void nvmet_ns_changed(struct nvmet_subsys *subsys, 
u32 nsid)
 
list_for_each_entry(ctrl, >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);
@@ -855,6 +857,7 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char 
*hostnqn,
 
kref_init(>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);
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 8cdc1e550396..f4d16d9b3582 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -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 intnr_async_event_cmds;
struct list_headasync_events;
-- 
2.17.0