nvmet: synchronize sqhd update
Subsystems (2)
PATCH v4 1/1 nvmet: synchronize sqhd update
In testing target io in read write mix, we did indeed get into cases where sqhd didn't update properly and slowly missed enough updates to shutdown the queue.
Protect the updating sqhd by using cmpxchg
Signed-off-by James Smart <james.smart at broadcom.com>
---
v2: move locks so around update and assignment
v3: convert to cmpxchg
v4: as u16 cmpxchg appears to not always be supported, convert sqhd to u32
--- drivers/nvme/target/core.c | 15 ++++++++++++--- drivers/nvme/target/nvmet.h | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-)
drivers/nvme/target/core.c +12 -3
@@ -387,12 +387,21 @@ struct nvmet_ns *nvmet_ns_alloc(struct nvmet_subsys *subsys, u32 nsid)static void __nvmet_req_complete (struct nvmet_req *req,u16 status) { +u32 old_sqhd, new_sqhd; +u16 sqhd; +if (status)nvmet_set_status (req, status); -if (req->sq->size) - req->sq->sqhd = (req->sq->sqhd +1 ) % req->sq->size; - req->rsp->sq_head =cpu_to_le16 (req->sq->sqhd); +if (req->sq->size) { +do { + old_sqhd = req->sq->sqhd; + new_sqhd = (old_sqhd +1 ) % req->sq->size; + }while (cmpxchg (&req->sq->sqhd, old_sqhd, new_sqhd) != + old_sqhd); + } + sqhd = req->sq->sqhd &0x0000FFFF ; + req->rsp->sq_head =cpu_to_le16 (sqhd); req->rsp->sq_id =cpu_to_le16 (req->sq->qid); req->rsp->command_id = req->cmd->common.command_id;
drivers/nvme/target/nvmet.h +1 -1
@@ -74,7 +74,7 @@ struct nvmet_sq {struct percpu_ref ref;u16 qid;u16 size; -u16 sqhd; +u32 sqhd;struct completion free_done;struct completion confirm_done; };
Signature · 1 line
2.13.1
Christoph Hellwig
AppliedPATCH v4 1/1 nvmet: synchronize sqhd update
Quoted 7 lines · James Smart
In testing target io in read write mix, we did indeed get into cases where sqhd didn't update properly and slowly missed enough updates to shutdown the queue.
Protect the updating sqhd by using cmpxchg
Signed-off-by James Smart <james.smart at broadcom.com>
Applied to nvme-4.14 with a small changelog fixup.