memif_dev_close() enqueued a disconnect message but never flushed it and
never tore down the control channel, so when a port is closed without a
preceding dev_stop the control-channel interrupt callback, its file
descriptor and the pmd->cc allocation were leaked. Call memif_disconnect()
from close, which flushes the queued disconnect and releases the control
channel. memif_disconnect() is guarded on pmd->cc and clears it, so it is
safe when dev_stop already ran.

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

Fixes: 09c7e63a71f9 ("net/memif: introduce memory interface PMD")
Cc: [email protected]

Signed-off-by: Sriram Yagnaraman <[email protected]>
---
 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 5918406271..6f10e8d970 100644
--- a/drivers/net/memif/memif_socket.c
+++ b/drivers/net/memif/memif_socket.c
@@ -664,6 +664,9 @@ memif_disconnect(struct rte_eth_dev *dev)
                                continue;
                }
 
+               if (mq == NULL)
+                       continue;
+
                if (rte_intr_fd_get(mq->intr_handle) >= 0) {
                        close(rte_intr_fd_get(mq->intr_handle));
                        rte_intr_fd_set(mq->intr_handle, -1);
@@ -682,6 +685,9 @@ memif_disconnect(struct rte_eth_dev *dev)
                                continue;
                }
 
+               if (mq == NULL)
+                       continue;
+
                if (rte_intr_fd_get(mq->intr_handle) >= 0) {
                        close(rte_intr_fd_get(mq->intr_handle));
                        rte_intr_fd_set(mq->intr_handle, -1);
diff --git a/drivers/net/memif/rte_eth_memif.c 
b/drivers/net/memif/rte_eth_memif.c
index d805509391..43049fddc5 100644
--- a/drivers/net/memif/rte_eth_memif.c
+++ b/drivers/net/memif/rte_eth_memif.c
@@ -1718,6 +1718,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

Reply via email to