From: Wenjie Sun Date: Mon, 28 Jan 2019 06:55:49 +0000 (+0800) Subject: vhost: fix deadlock in driver unregister X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=054617fd82b6d99595520e75fdab6706f39d5643;p=dpdk.git vhost: fix deadlock in driver unregister In rte_vhost_driver_unregister(), the connection fd is removed from the fdset using fdset_try_del(). Call to this function may fail if the corresponding fd is in busy state, indicating that event dispatcher is executing the read or write callback on this fd. When it happens, rte_vhost_driver_unregister() keeps trying to remove the fd from the set until it is no more busy. This situation is causing a deadlock, because rte_vhost_driver_unregister() keeps trying to remove the fd from the set with vhost_user.mutex held, while the callback executed by the dispatcher, vhost_user_read_cb(), also takes this mutex at numerous places. The fix consists in releasing vhost_user.mutex between each retry in vhost_driver_unregister(). Fixes: 8b4b949144b8 ("vhost: fix dead lock on closing in server mode") Cc: stable@dpdk.org Signed-off-by: Wenjie Sun Reviewed-by: Maxime Coquelin --- diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c index 9cf34ad17a..9883b0491c 100644 --- a/lib/librte_vhost/socket.c +++ b/lib/librte_vhost/socket.c @@ -961,13 +961,13 @@ rte_vhost_driver_unregister(const char *path) int count; struct vhost_user_connection *conn, *next; +again: pthread_mutex_lock(&vhost_user.mutex); for (i = 0; i < vhost_user.vsocket_cnt; i++) { struct vhost_user_socket *vsocket = vhost_user.vsockets[i]; if (!strcmp(vsocket->path, path)) { -again: pthread_mutex_lock(&vsocket->conn_mutex); for (conn = TAILQ_FIRST(&vsocket->conn_list); conn != NULL; @@ -983,6 +983,7 @@ again: conn->connfd) == -1) { pthread_mutex_unlock( &vsocket->conn_mutex); + pthread_mutex_unlock(&vhost_user.mutex); goto again; }