[dpdk-dev] [PATCH] vhost: fix double free on shutdown

Tomasz Kulasek tomaszx.kulasek at intel.com
Fri Feb 9 18:14:55 CET 2018


The vhost connection can be closed concurrently from 2 places:
 * the connection thread itself
 * rte_vhost_driver_unregister

The connection thread will terminate the connection if any recv error
occurred. The unregister function will terminate the connection together
with the thread. However, there is no sychronization between those two.
The connection thread runs in the background without any mutex.

The rte_vhost_driver_unregister now signals the connection thread
to terminate itself and waits until it's killed.

Fixes: 65388b43f592 ("vhost: fix fd leaks for vhost-user server mode")
Cc: yuanhan.liu at linux.intel.com
Cc: stable at dpdk.org

Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk at intel.com>
Signed-off-by: Tomasz Kulasek <tomaszx.kulasek at intel.com>
---
 lib/librte_vhost/socket.c | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index 83befdced..46ac88efd 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -735,7 +735,7 @@ rte_vhost_driver_unregister(const char *path)
 {
 	int i;
 	int count;
-	struct vhost_user_connection *conn, *next;
+	struct vhost_user_connection *conn;
 
 	pthread_mutex_lock(&vhost_user.mutex);
 
@@ -752,22 +752,17 @@ rte_vhost_driver_unregister(const char *path)
 			}
 
 			pthread_mutex_lock(&vsocket->conn_mutex);
-			for (conn = TAILQ_FIRST(&vsocket->conn_list);
-			     conn != NULL;
-			     conn = next) {
-				next = TAILQ_NEXT(conn, next);
-
-				fdset_del(&vhost_user.fdset, conn->connfd);
-				RTE_LOG(INFO, VHOST_CONFIG,
-					"free connfd = %d for device '%s'\n",
-					conn->connfd, path);
+			TAILQ_FOREACH(conn, &vsocket->conn_list, next) {
 				close(conn->connfd);
-				vhost_destroy_device(conn->vid);
-				TAILQ_REMOVE(&vsocket->conn_list, conn, next);
-				free(conn);
 			}
 			pthread_mutex_unlock(&vsocket->conn_mutex);
 
+			do {
+				pthread_mutex_lock(&vsocket->conn_mutex);
+				conn = TAILQ_FIRST(&vsocket->conn_list);
+				pthread_mutex_unlock(&vsocket->conn_mutex);
+			} while (conn != NULL);
+
 			pthread_mutex_destroy(&vsocket->conn_mutex);
 			free(vsocket->path);
 			free(vsocket);
-- 
2.14.1



More information about the dev mailing list