vhost: fix deadlock when vhost unregister.
Checks
Commit Message
When rte_vhost_driver_unregister delete the connection fd,
fdset_try_del will always try and donot release the
vhostuser.mutex if the fd is busy, but the fdset_event_dispatch
will set the fd to busy and call vhost_user_msg_handler to get
vhostuser.mutex, which will cause deadlock. Unlock the
vhost_user.mutexif fdset_try_del fail and relock it when retry.
Signed-off-by: findtheonlway <findtheonlyway@gmail.com>
Signed-off-by: sunwenjie <sunwenjie@didichuxing.com>
---
lib/librte_vhost/socket.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
Comments
Hi,
On 01/11, sunwenjie wrote:
> When rte_vhost_driver_unregister delete the connection fd,
> fdset_try_del will always try and donot release the
> vhostuser.mutex if the fd is busy, but the fdset_event_dispatch
> will set the fd to busy and call vhost_user_msg_handler to get
> vhostuser.mutex, which will cause deadlock. Unlock the
> vhost_user.mutexif fdset_try_del fail and relock it when retry.
>
> Signed-off-by: findtheonlway <findtheonlyway@gmail.com>
> Signed-off-by: sunwenjie <sunwenjie@didichuxing.com>
The commit log and Signed-off-by tage should not be indented, and you should
get you commit log checked by `./devtools/check-git-log.sh -1`, and fix all the
errors it shows.
Btw, I think this is your v2 patch, and you should add the v2 tag in the
subject.
Thanks,
Xiaolong
>---
> lib/librte_vhost/socket.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
>diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
>index 9cf34ad17..7959c5ece 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;
>@@ -981,6 +981,7 @@ rte_vhost_driver_unregister(const char *path)
> */
> if (fdset_try_del(&vhost_user.fdset,
> conn->connfd) == -1) {
>+ pthread_mutex_unlock(&vhost_user.mutex);
> pthread_mutex_unlock(
> &vsocket->conn_mutex);
> goto again;
>--
>2.20.1
>
@@ -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;
@@ -981,6 +981,7 @@ rte_vhost_driver_unregister(const char *path)
*/
if (fdset_try_del(&vhost_user.fdset,
conn->connfd) == -1) {
+ pthread_mutex_unlock(&vhost_user.mutex);
pthread_mutex_unlock(
&vsocket->conn_mutex);
goto again;