Skip to content

Commit a208fc5

Browse files
maurizio-lombardiChristoph Hellwig
authored andcommitted
nvmet-tcp: fix a race condition between release_queue and io_work
If the initiator executes a reset controller operation while performing I/O, the target kernel will crash because of a race condition between release_queue and io_work; nvmet_tcp_uninit_data_in_cmds() may be executed while io_work is running, calling flush_work() was not sufficient to prevent this because io_work could requeue itself. Fix this bug by using cancel_work_sync() to prevent io_work from requeuing itself and set rcv_state to NVMET_TCP_RECV_ERR to make sure we don't receive any more data from the socket. Signed-off-by: Maurizio Lombardi <[email protected]> Reviewed-by: Keith Busch <[email protected]> Reviewed-by: Sagi Grimberg <[email protected]> Reviewed-by: John Meneghini <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]>
1 parent efcf593 commit a208fc5

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

drivers/nvme/target/tcp.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1437,7 +1437,9 @@ static void nvmet_tcp_release_queue_work(struct work_struct *w)
14371437
mutex_unlock(&nvmet_tcp_queue_mutex);
14381438

14391439
nvmet_tcp_restore_socket_callbacks(queue);
1440-
flush_work(&queue->io_work);
1440+
cancel_work_sync(&queue->io_work);
1441+
/* stop accepting incoming data */
1442+
queue->rcv_state = NVMET_TCP_RECV_ERR;
14411443

14421444
nvmet_tcp_uninit_data_in_cmds(queue);
14431445
nvmet_sq_destroy(&queue->nvme_sq);

0 commit comments

Comments
 (0)