[PATCH V2] nvme-tcp: Prevent infinite loop if socket closes during CONNECTING state

Maurizio Lombardi mlombard at redhat.com
Mon Jan 27 08:51:20 PST 2025


There is a potential race condition that can occur if
the target closes the socket while the host is in the CONNECTING state.

If the socket's state changes to TCP_CLOSE, the nvme_tcp_state_change()
function is invoked. However, nvme_tcp_error_recovery() is unable
to transition the controller state to NVME_CTRL_RESETTING because
the controller is still in the CONNECTING state. As a result, error
recovery is bypassed, and the controller incorrectly transitions
to the LIVE state with closed sockets.

Subsequent attempts by the host to communicate with the target
will result in an infinite loop.

Fix the bug by checking for the -EPIPE error in nvme_tcp_try_send()
function and initiating error recovery to handle disconnection cases
missed during the CONNECTING-to-LIVE transition.

Signed-off-by: Maurizio Lombardi <mlombard at redhat.com>
---

v2: commit message: clarify where the error code is checked

 drivers/nvme/host/tcp.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index 841238f38fdd..d0bb225dca23 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -1261,6 +1261,8 @@ static int nvme_tcp_try_send(struct nvme_tcp_queue *queue)
 			"failed to send request %d\n", ret);
 		nvme_tcp_fail_request(queue->request);
 		nvme_tcp_done_send_req(queue);
+		if (ret == -EPIPE)
+			nvme_tcp_error_recovery(&queue->ctrl->ctrl);
 	}
 out:
 	memalloc_noreclaim_restore(noreclaim_flag);
-- 
2.43.5




More information about the Linux-nvme mailing list