From 3f98ce65a87979e881343dcf082c9595ec90ddc7 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Wed, 28 Oct 2026 10:42:21 -0600 Subject: [PATCH] nvmet-tcp: don't read a removed port at Connect time nvmet_tcp_alloc_cmd() takes the nvmet port of a command from queue->port, and the commands of a queue are allocated from the io work when the Connect arrives. nvmet_tcp_remove_port() shuts down the queues that have no controller yet and frees the port without waiting for them, they're released later from a work. An io work handling a Connect at that moment reads the freed port for every command of the queue and hands the result to the core. Note the nvmet port in the queue at allocation. It outlives the transport port. Fixes: 872d26a391da ("nvmet-tcp: add NVMe over TCP target driver") Cc: Christoph Hellwig Cc: Sagi Grimberg Cc: Chaitanya Kulkarni Signed-off-by: Josef Bacik Signed-off-by: Jens Axboe Signed-off-by: Keith Busch --- drivers/nvme/target/tcp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index 84af7d1bc588..85a10679d0a9 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -166,6 +166,7 @@ enum nvmet_tcp_queue_state { struct nvmet_tcp_queue { struct socket *sock; struct nvmet_tcp_port *port; + struct nvmet_port *nport; struct work_struct io_work; struct nvmet_cq nvme_cq; struct nvmet_sq nvme_sq; @@ -1512,7 +1513,7 @@ static int nvmet_tcp_alloc_cmd(struct nvmet_tcp_queue *queue, u8 hdgst = nvmet_tcp_hdgst_len(queue); c->queue = queue; - c->req.port = queue->port->nport; + c->req.port = queue->nport; c->cmd_pdu = page_frag_alloc(&queue->pf_cache, sizeof(*c->cmd_pdu) + hdgst, GFP_KERNEL | __GFP_ZERO); @@ -1969,6 +1970,8 @@ static void nvmet_tcp_alloc_queue(struct nvmet_tcp_port *port, kref_init(&queue->kref); queue->sock = newsock; queue->port = port; + /* The port may be gone when the commands are allocated */ + queue->nport = port->nport; queue->nr_cmds = 0; spin_lock_init(&queue->state_lock); if (queue->port->nport->disc_addr.tsas.tcp.sectype ==