From 6552819e087ff63ffe849d33f34a60b1c19a6b1f Mon Sep 17 00:00:00 2001 From: Maurizio Lombardi Date: Tue, 21 Jan 2025 13:52:32 +0100 Subject: [PATCH] nvme-tcp: Prevent infinite loop if socket closes during CONNECTING state 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 code, which indicates that the connection was closed by the target. If this condition is detected, ensure the error recovery process is initiated to correctly handle the disconnection. Signed-off-by: Maurizio Lombardi --- 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