diff mbox

[09/14] nvmet: Add AEN configuration support

Message ID 20180526102735.31404-10-hch@lst.de (mailing list archive)
State New, archived
Headers show

Commit Message

Christoph Hellwig May 26, 2018, 10:27 a.m. UTC
From: Hannes Reinecke <hare@suse.com>

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>
---
 drivers/nvme/target/admin-cmd.c | 13 ++++++++++++-
 drivers/nvme/target/core.c      |  3 +++
 drivers/nvme/target/nvmet.h     |  3 +++
 3 files changed, 18 insertions(+), 1 deletion(-)

Comments

Johannes Thumshirn May 28, 2018, 6:54 a.m. UTC | #1
Looks good,
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Daniel Verkamp May 29, 2018, 5:15 p.m. UTC | #2
[...]
> diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-
> cmd.c
> index 82d521f60a43..20d9ce5064f8 100644
> --- a/drivers/nvme/target/admin-cmd.c
> +++ b/drivers/nvme/target/admin-cmd.c
> @@ -432,6 +432,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;
> +		val32 = le32_to_cpu(req->cmd->common.cdw10[1]);
> +		if (val32 & ~NVMET_AEN_SUPPORTED) {
> +			status = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
> +			break;
> +		}

This looks overly restrictive - a host sending a Set Features with e.g. the health critical warning bits set in CDW11 will get a failure.  As far as I can tell, this isn't allowed by the spec;  Set Features - Asynchronous Event Configuration and the health log page have been mandatory since NVMe 1.0, and presumably support for the corresponding health log page related AER bits is also mandatory (these were the only bits available in NVMe 1.0).  I think it should be fine to just allow the user to set any (valid) combination of bits here, while still only triggering the NS Changed notification.

Thanks,
-- Daniel
Christoph Hellwig May 29, 2018, 5:29 p.m. UTC | #3
On Tue, May 29, 2018 at 05:15:34PM +0000, Verkamp, Daniel wrote:
> This looks overly restrictive - a host sending a Set Features with e.g. the health critical warning bits set in CDW11 will get a failure.  As far as I can tell, this isn't allowed by the spec;  Set Features - Asynchronous Event Configuration and the health log page have been mandatory since NVMe 1.0, and presumably support for the corresponding health log page related AER bits is also mandatory (these were the only bits available in NVMe 1.0).

Agreed so far.

> I think it should be fine to just allow the user to set any (valid) combination of bits here, while still only triggering the NS Changed notification.

Disagreeing here.  Catching completely bogus bits that the hosts sets
is important.
Daniel Verkamp May 29, 2018, 5:35 p.m. UTC | #4
> -----Original Message-----
> From: Christoph Hellwig [mailto:hch@lst.de]
> Sent: Tuesday, May 29, 2018 10:30 AM
> To: Verkamp, Daniel <daniel.verkamp@intel.com>
> Cc: Christoph Hellwig <hch@lst.de>; linux-nvme@lists.infradead.org; Jens Axboe
> <axboe@kernel.dk>; linux-block@vger.kernel.org; Hannes Reinecke
> <hare@suse.com>; Sagi Grimberg <sagi@grimberg.me>; Busch, Keith
> <keith.busch@intel.com>; Hannes Reinecke <hare@suse.de>
> Subject: Re: [PATCH 09/14] nvmet: Add AEN configuration support
> 
> On Tue, May 29, 2018 at 05:15:34PM +0000, Verkamp, Daniel wrote:
> > This looks overly restrictive - a host sending a Set Features with e.g. the health
> critical warning bits set in CDW11 will get a failure.  As far as I can tell, this isn't
> allowed by the spec;  Set Features - Asynchronous Event Configuration and the
> health log page have been mandatory since NVMe 1.0, and presumably support
> for the corresponding health log page related AER bits is also mandatory (these
> were the only bits available in NVMe 1.0).
> 
> Agreed so far.
> 
> > I think it should be fine to just allow the user to set any (valid) combination of
> bits here, while still only triggering the NS Changed notification.
> 
> Disagreeing here.  Catching completely bogus bits that the hosts sets
> is important.

Sorry, I should have been clearer - I agree with your position here.  Only bits that are valid should be allowed, so for example it is fine to fail commands that set reserved bits, or optional bits that have a mechanism to indicate they are not supported, like Telemetry (which has an associated bit in Identify controller data - LPA).  My note above was really just about the health warning bits, which by my reading are not optional.

Thanks,
-- Daniel
Christoph Hellwig May 29, 2018, 5:45 p.m. UTC | #5
On Tue, May 29, 2018 at 05:35:12PM +0000, Verkamp, Daniel wrote:
> Sorry, I should have been clearer - I agree with your position here.  Only bits that are valid should be allowed, so for example it is fine to fail commands that set reserved bits, or optional bits that have a mechanism to indicate they are not supported, like Telemetry (which has an associated bit in Identify controller data - LPA).  My note above was really just about the health warning bits, which by my reading are not optional.

Yes, I think your reading is right and we should not fail those bits.
I'll fix it for the next version.
diff mbox

Patch

diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
index 82d521f60a43..20d9ce5064f8 100644
--- a/drivers/nvme/target/admin-cmd.c
+++ b/drivers/nvme/target/admin-cmd.c
@@ -432,6 +432,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_SUPPORTED) {
+			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;
@@ -470,9 +480,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 424ad41af980..53e2386b73cf 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -162,6 +162,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, 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);
@@ -849,6 +851,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_SUPPORTED);
 
 	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 bcd88b5c9d99..50c8300ea572 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -30,6 +30,8 @@ 
 #define NVMET_ASYNC_EVENTS		4
 #define NVMET_ERROR_LOG_SLOTS		128
 
+#define NVMET_AEN_SUPPORTED	NVME_AEN_CFG_NS_ATTR
+
 /* 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 +125,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;