|
@@ -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;
|
|
|
|