diff options
author | James Smart <jsmart2021@gmail.com> | 2017-09-18 12:08:29 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2017-09-25 10:56:05 -0400 |
commit | bb1cc74790eb51f52d23c6e5fd9a3bb16030c3d8 (patch) | |
tree | 1590f612ebe76d8a04090d7140d65c3bd84c7346 | |
parent | 8edd11c9ad3a6205eea6de9d02eaf64c681a0658 (diff) |
nvmet: implement valid sqhd values in completions
To support sqhd, for initiators that are following the spec and
paying attention to sqhd vs their sqtail values:
- add sqhd to struct nvmet_sq
- initialize sqhd to 0 in nvmet_sq_setup
- rather than propagate the 0's-based qsize value from the connect message
which requires a +1 in every sqhd update, and as nothing else references
it, convert to 1's-based value in nvmt_sq/cq_setup() calls.
- validate connect message sqsize being non-zero per spec.
- updated assign sqhd for every completion that goes back.
Also remove handling the NULL sq case in __nvmet_req_complete, as it can't
happen with the current code.
Signed-off-by: James Smart <james.smart@broadcom.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Max Gurtovoy <maxg@mellanox.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | drivers/nvme/target/core.c | 8 | ||||
-rw-r--r-- | drivers/nvme/target/fabrics-cmd.c | 9 | ||||
-rw-r--r-- | drivers/nvme/target/nvmet.h | 1 |
3 files changed, 12 insertions, 6 deletions
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 7c23eaf8e563..c2a768a94235 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c | |||
@@ -390,10 +390,9 @@ static void __nvmet_req_complete(struct nvmet_req *req, u16 status) | |||
390 | if (status) | 390 | if (status) |
391 | nvmet_set_status(req, status); | 391 | nvmet_set_status(req, status); |
392 | 392 | ||
393 | /* XXX: need to fill in something useful for sq_head */ | 393 | req->sq->sqhd = (req->sq->sqhd + 1) % req->sq->size; |
394 | req->rsp->sq_head = 0; | 394 | req->rsp->sq_head = cpu_to_le16(req->sq->sqhd); |
395 | if (likely(req->sq)) /* may happen during early failure */ | 395 | req->rsp->sq_id = cpu_to_le16(req->sq->qid); |
396 | req->rsp->sq_id = cpu_to_le16(req->sq->qid); | ||
397 | req->rsp->command_id = req->cmd->common.command_id; | 396 | req->rsp->command_id = req->cmd->common.command_id; |
398 | 397 | ||
399 | if (req->ns) | 398 | if (req->ns) |
@@ -420,6 +419,7 @@ void nvmet_cq_setup(struct nvmet_ctrl *ctrl, struct nvmet_cq *cq, | |||
420 | void nvmet_sq_setup(struct nvmet_ctrl *ctrl, struct nvmet_sq *sq, | 419 | void nvmet_sq_setup(struct nvmet_ctrl *ctrl, struct nvmet_sq *sq, |
421 | u16 qid, u16 size) | 420 | u16 qid, u16 size) |
422 | { | 421 | { |
422 | sq->sqhd = 0; | ||
423 | sq->qid = qid; | 423 | sq->qid = qid; |
424 | sq->size = size; | 424 | sq->size = size; |
425 | 425 | ||
diff --git a/drivers/nvme/target/fabrics-cmd.c b/drivers/nvme/target/fabrics-cmd.c index 859a66725291..db3bf6b8bf9e 100644 --- a/drivers/nvme/target/fabrics-cmd.c +++ b/drivers/nvme/target/fabrics-cmd.c | |||
@@ -109,9 +109,14 @@ static u16 nvmet_install_queue(struct nvmet_ctrl *ctrl, struct nvmet_req *req) | |||
109 | pr_warn("queue already connected!\n"); | 109 | pr_warn("queue already connected!\n"); |
110 | return NVME_SC_CONNECT_CTRL_BUSY | NVME_SC_DNR; | 110 | return NVME_SC_CONNECT_CTRL_BUSY | NVME_SC_DNR; |
111 | } | 111 | } |
112 | if (!sqsize) { | ||
113 | pr_warn("queue size zero!\n"); | ||
114 | return NVME_SC_CONNECT_INVALID_PARAM | NVME_SC_DNR; | ||
115 | } | ||
112 | 116 | ||
113 | nvmet_cq_setup(ctrl, req->cq, qid, sqsize); | 117 | /* note: convert queue size from 0's-based value to 1's-based value */ |
114 | nvmet_sq_setup(ctrl, req->sq, qid, sqsize); | 118 | nvmet_cq_setup(ctrl, req->cq, qid, sqsize + 1); |
119 | nvmet_sq_setup(ctrl, req->sq, qid, sqsize + 1); | ||
115 | return 0; | 120 | return 0; |
116 | } | 121 | } |
117 | 122 | ||
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index 7d261ab894f4..7b8e20adf760 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h | |||
@@ -74,6 +74,7 @@ struct nvmet_sq { | |||
74 | struct percpu_ref ref; | 74 | struct percpu_ref ref; |
75 | u16 qid; | 75 | u16 qid; |
76 | u16 size; | 76 | u16 size; |
77 | u16 sqhd; | ||
77 | struct completion free_done; | 78 | struct completion free_done; |
78 | struct completion confirm_done; | 79 | struct completion confirm_done; |
79 | }; | 80 | }; |