nvmet: allow Keep Alive for Discovery controller
authorJay Sternberg <jay.e.sternberg@intel.com>
Mon, 12 Nov 2018 21:56:35 +0000 (13:56 -0800)
committerJens Axboe <axboe@kernel.dk>
Sat, 8 Dec 2018 05:26:56 +0000 (22:26 -0700)
Per change to specification allowing Discovery controllers to have
explicit persistent connections, remove restriction on Discovery
controllers allowing kato on connect.

Signed-off-by: Jay Sternberg <jay.e.sternberg@intel.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/nvme/target/admin-cmd.c
drivers/nvme/target/core.c
drivers/nvme/target/discovery.c
drivers/nvme/target/nvmet.h

index 2e89f4e..ad94119 100644 (file)
@@ -726,7 +726,7 @@ static void nvmet_execute_async_event(struct nvmet_req *req)
        schedule_work(&ctrl->async_event_work);
 }
 
-static void nvmet_execute_keep_alive(struct nvmet_req *req)
+void nvmet_execute_keep_alive(struct nvmet_req *req)
 {
        struct nvmet_ctrl *ctrl = req->sq->ctrl;
 
index f42a105..46345c3 100644 (file)
@@ -1180,31 +1180,17 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,
        ctrl->cntlid = ret;
 
        ctrl->ops = req->ops;
-       if (ctrl->subsys->type == NVME_NQN_DISC) {
-               /* Don't accept keep-alive timeout for discovery controllers */
-               if (kato) {
-                       status = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
-                       goto out_remove_ida;
-               }
 
-               /*
-                * Discovery controllers use some arbitrary high value in order
-                * to cleanup stale discovery sessions
-                *
-                * From the latest base diff RC:
-                * "The Keep Alive command is not supported by
-                * Discovery controllers. A transport may specify a
-                * fixed Discovery controller activity timeout value
-                * (e.g., 2 minutes).  If no commands are received
-                * by a Discovery controller within that time
-                * period, the controller may perform the
-                * actions for Keep Alive Timer expiration".
-                */
-               ctrl->kato = NVMET_DISC_KATO;
-       } else {
-               /* keep-alive timeout in seconds */
-               ctrl->kato = DIV_ROUND_UP(kato, 1000);
-       }
+       /*
+        * Discovery controllers may use some arbitrary high value
+        * in order to cleanup stale discovery sessions
+        */
+       if ((ctrl->subsys->type == NVME_NQN_DISC) && !kato)
+               kato = NVMET_DISC_KATO_MS;
+
+       /* keep-alive timeout in seconds */
+       ctrl->kato = DIV_ROUND_UP(kato, 1000);
+
        nvmet_start_keep_alive_timer(ctrl);
 
        mutex_lock(&subsys->lock);
@@ -1215,8 +1201,6 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,
        *ctrlp = ctrl;
        return 0;
 
-out_remove_ida:
-       ida_simple_remove(&cntlid_ida, ctrl->cntlid);
 out_free_sqs:
        kfree(ctrl->sqs);
 out_free_cqs:
index bc0aa0b..6e0f91e 100644 (file)
@@ -194,6 +194,10 @@ u16 nvmet_parse_discovery_cmd(struct nvmet_req *req)
        }
 
        switch (cmd->common.opcode) {
+       case nvme_admin_keep_alive:
+               req->execute = nvmet_execute_keep_alive;
+               req->data_len = 0;
+               return 0;
        case nvme_admin_get_log_page:
                req->data_len = nvmet_get_log_page_len(cmd);
 
index 8ddc54f..c525fb0 100644 (file)
@@ -372,6 +372,8 @@ void nvmet_req_complete(struct nvmet_req *req, u16 status);
 int nvmet_req_alloc_sgl(struct nvmet_req *req);
 void nvmet_req_free_sgl(struct nvmet_req *req);
 
+void nvmet_execute_keep_alive(struct nvmet_req *req);
+
 void nvmet_cq_setup(struct nvmet_ctrl *ctrl, struct nvmet_cq *cq, u16 qid,
                u16 size);
 void nvmet_sq_setup(struct nvmet_ctrl *ctrl, struct nvmet_sq *sq, u16 qid,
@@ -442,7 +444,7 @@ u32 nvmet_get_log_page_len(struct nvme_command *cmd);
 #define NVMET_DEFAULT_ANA_GRPID        1
 
 #define NVMET_KAS              10
-#define NVMET_DISC_KATO                120
+#define NVMET_DISC_KATO_MS             120000
 
 int __init nvmet_init_configfs(void);
 void __exit nvmet_exit_configfs(void);