[PATCH v3 7/9] net/memif: disconnect on device close

Sriram Yagnaraman sriram.yagnaraman at ericsson.com
Fri Oct 16 16:15:55 CEST 2026


memif_dev_close() enqueued a disconnect message but never flushed it and
never tore down the control channel, leaking the control-channel
interrupt callback, its file descriptor and the pmd->cc allocation.

The leak is reachable on a server that was started and then stopped.
memif_create() sets ETH_MEMIF_FLAG_DISABLED and memif_connect_server()
clears it at dev_start, but dev_stop does not set it again, so after a
stop memif_msg_receive_init() still accepts a peer: pmd->cc is bound and
the port is left with a live control channel at close. (A never-started
server keeps the flag set and rejects the peer, so pmd->cc stays NULL.)
Call memif_disconnect() from close to flush the queued disconnect and
release the control channel; it is guarded on pmd->cc and clears it, so
it is safe when dev_stop already ran. The companion dev_stop fix that
refuses peers while stopped is a separate patch; this call remains as a
backstop for an init racing with stop.

memif_disconnect() also walked the per-queue interrupt handles indexed
by the configured ring count without checking that the queue pointer was
set. Closing a device that was configured but never started (so queues
were never allocated) then dereferenced a NULL queue; skip NULL queue
entries.

Fixes: 09c7e63a71f9 ("net/memif: introduce memory interface PMD")
Cc: stable at dpdk.org

Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman at ericsson.com>
---
 drivers/net/memif/memif_socket.c  | 6 ++++++
 drivers/net/memif/rte_eth_memif.c | 4 ++++
 2 files changed, 10 insertions(+)

diff --git a/drivers/net/memif/memif_socket.c b/drivers/net/memif/memif_socket.c
index 550e2e468a..cdf85e09a1 100644
--- a/drivers/net/memif/memif_socket.c
+++ b/drivers/net/memif/memif_socket.c
@@ -663,6 +663,9 @@ memif_disconnect(struct rte_eth_dev *dev)
 				continue;
 		}
 
+		if (mq == NULL)
+			continue;
+
 		rte_intr_fd_close(mq->intr_handle);
 	}
 	for (i = 0; i < pmd->cfg.num_s2c_rings; i++) {
@@ -678,6 +681,9 @@ memif_disconnect(struct rte_eth_dev *dev)
 				continue;
 		}
 
+		if (mq == NULL)
+			continue;
+
 		rte_intr_fd_close(mq->intr_handle);
 	}
 
diff --git a/drivers/net/memif/rte_eth_memif.c b/drivers/net/memif/rte_eth_memif.c
index 852a7e2e8e..cdf77d77b0 100644
--- a/drivers/net/memif/rte_eth_memif.c
+++ b/drivers/net/memif/rte_eth_memif.c
@@ -1723,6 +1723,10 @@ memif_dev_close(struct rte_eth_dev *dev)
 
 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
 		memif_msg_enq_disconnect(pmd->cc, "Device closed", 0);
+		/* Flush the disconnect and tear down the control channel;
+		 * memif_disconnect() is idempotent if dev_stop already ran.
+		 */
+		memif_disconnect(dev);
 
 		for (i = 0; i < dev->data->nb_rx_queues; i++)
 			memif_rx_queue_release(dev, i);
-- 
2.43.7



More information about the dev mailing list