rte_vhost: fix double free on shutdown

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
occured. 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.

Change-Id: I012e97ebb8a79edcb2c17c28b2fc7e8041bf92b3
Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/383085
Reviewed-by: Pawel Wodkowski <pawelx.wodkowski@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
Dariusz Stojaczyk 2017-10-19 16:07:11 +02:00 committed by Daniel Verkamp
parent f26983fa07
commit 3788c907bb

View File

@ -713,9 +713,7 @@ rte_vhost_driver_unregister(const char *path)
{
int i;
int count;
struct vhost_user_connection *conn, *next;
struct vhost_user_connection_list del_conn_list =
TAILQ_HEAD_INITIALIZER(del_conn_list);
struct vhost_user_connection *conn;
pthread_mutex_lock(&vhost_user.mutex);
@ -732,25 +730,16 @@ 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);
TAILQ_REMOVE(&vsocket->conn_list, conn, next);
TAILQ_INSERT_TAIL(&del_conn_list, conn, next);
TAILQ_FOREACH(conn, &vsocket->conn_list, next) {
close(conn->connfd);
}
pthread_mutex_unlock(&vsocket->conn_mutex);
TAILQ_FOREACH(conn, &del_conn_list, next) {
fdset_del(&vhost_user.fdset, conn->connfd);
RTE_LOG(INFO, VHOST_CONFIG,
"free connfd = %d for device '%s'\n",
conn->connfd, path);
close(conn->connfd);
vhost_destroy_device(conn->vid);
free(conn);
}
do {
pthread_mutex_lock(&vsocket->conn_mutex);
conn = TAILQ_FIRST(&vsocket->conn_list);
pthread_mutex_unlock(&vsocket->conn_mutex);
} while (conn != NULL);
free(vsocket->path);
free(vsocket);