mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
nvmet: don't clear sq->ctrl for a Connect with sqsize 0
nvmet_install_queue() checks sqsize first and jumps to err on zero, where sq->ctrl is set to NULL. Since commitb71df12605the cmpxchg() that sets sq->ctrl comes after the checks, so err now undoes a bind that this call never made. Over RDMA a host can send two Connects together and the second is parsed before the first executes, so a second Connect with sqsize 0 clears the sq->ctrl the first one set. The reference it held is never dropped and the controller leaks, with its cntlid, until reboot. The discovery subsystem lets any host do that, 20 connections leak around 10 controllers. A pending AER on such a queue hangs nvmet_sq_destroy() forever, and a queue can keep its "authenticated" mark across a rebind. Return the status directly, as the two checks after it do, so err is only reached after this call's cmpxchg() succeeded. Fixes:b71df12605("nvmet: avoid duplicate qid in connect cmd") Cc: Christoph Hellwig <hch@lst.de> Cc: Sagi Grimberg <sagi@grimberg.me> Cc: Chaitanya Kulkarni <kch@nvidia.com> Signed-off-by: Chris Mason <mason@kernel.org> Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Keith Busch <kbusch@kernel.org>
This commit is contained in:
parent
f1dac2a2e7
commit
89480d137b
|
|
@ -186,8 +186,7 @@ static u16 nvmet_install_queue(struct nvmet_ctrl *ctrl, struct nvmet_req *req)
|
|||
pr_warn("queue size zero!\n");
|
||||
req->error_loc = offsetof(struct nvmf_connect_command, sqsize);
|
||||
req->cqe->result.u32 = IPO_IATTR_CONNECT_SQE(sqsize);
|
||||
ret = NVME_SC_CONNECT_INVALID_PARAM | NVME_STATUS_DNR;
|
||||
goto err;
|
||||
return NVME_SC_CONNECT_INVALID_PARAM | NVME_STATUS_DNR;
|
||||
}
|
||||
|
||||
if (ctrl->sqs[qid] != NULL) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user