From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr0-f171.google.com (mail-wr0-f171.google.com [209.85.128.171]) by dpdk.org (Postfix) with ESMTP id F018B1B854 for ; Tue, 15 May 2018 15:48:50 +0200 (CEST) Received: by mail-wr0-f171.google.com with SMTP id v5-v6so210336wrf.9 for ; Tue, 15 May 2018 06:48:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=NWzyDqM3FA/qdYpqsgzzfuEnq//zTNXSwXvlEU4OaPY=; b=HTky2hfabA09CBM3/RQ+U+PCoLaeeuLoUYqTRIIkzxcuPQmFqr8873/TXA+OxCf4oW r4W1zc4XjQ8PJMuOOnNIa8E7P3BkCtshI0/Qf8L+8DOxwTpakQz7bG3OLmTQ7ivzeYom +bKEDGWKNPUOhCP72c3UTBqqEdyMNod+4B4Jl+sFczQiGLWVeBjcvy8l0U/rLPIaE58P BEZlhzloftqJ7idaSl0+5jIvaubOKjSyINkYucV/IjuScmvjCBKxdO4y068ponBQ42wo ie8KUxmrcpqXPY4Mfo4GbFEWipz1LM82VaZqfjx/85YpC82+vEd+aYngpW6psnUnSIea 0uFQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=NWzyDqM3FA/qdYpqsgzzfuEnq//zTNXSwXvlEU4OaPY=; b=Iyeb4EpMf/OOiwDcrThaVSqc45wIwktO7cwS46JbtGTChTI/YS6+JDvXWaMuPCK/5V v1sviDglP9UZ0Kipk3cK9qDLOIwPRAtq0OQ0rn7hNG0AHmiTEz0ir7i0/c9t9EHTvzP/ W9Vy5NgWrcEiGrw9qu7db4TIeELje9fb9PtwwUErHar201n0e/hhRSARzb8VvIJdjvdj VbN86R1IeWO4jRk2KTgurm3H7LI+Jsm4ACGIOPc0DjAtN2SpD/3RPsxxbkBauSZLBIA8 dwsU2snbKkh27Le/9qXKdUodhdzej+wI251ylhM3Z2gcdClEyHxz9X5yoeDvBDYmzfo0 JatQ== X-Gm-Message-State: ALKqPwc/1qAfP8+SqTpbuv+annQXrO1roRn8kRV9POMU6ezOpiGTyz3x BiI7Ige043eVuEcvVbjfdJY= X-Google-Smtp-Source: AB8JxZqVgsjnLvhQkrGXebGgK6G038v6qlA0L3x79fwKSrdEiDeTj8VHO/ayvcjKZEJKpsg/uxWDEw== X-Received: by 2002:adf:9c01:: with SMTP id f1-v6mr10280053wrc.171.1526392130700; Tue, 15 May 2018 06:48:50 -0700 (PDT) Received: from localhost (slip139-92-244-193.lon.uk.prserv.net. [139.92.244.193]) by smtp.gmail.com with ESMTPSA id s14-v6sm688889wmb.5.2018.05.15.06.48.49 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 15 May 2018 06:48:49 -0700 (PDT) From: luca.boccassi@gmail.com To: Tonghao Zhang Cc: Maxime Coquelin , dpdk stable Date: Tue, 15 May 2018 14:46:52 +0100 Message-Id: <20180515134731.9337-41-luca.boccassi@gmail.com> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20180515134731.9337-1-luca.boccassi@gmail.com> References: <20180503110612.12146-2-luca.boccassi@gmail.com> <20180515134731.9337-1-luca.boccassi@gmail.com> Subject: [dpdk-stable] patch 'vhost: fix dead lock on closing in server mode' has been queued to stable release 18.02.2 X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 May 2018 13:48:51 -0000 Hi, FYI, your patch has been queued to stable release 18.02.2 Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet. It will be pushed if I get no objections before 05/16/18. So please shout if anyone has objections. Thanks. Luca Boccassi --- >>From 7a4840237ebeb339845f14bfb2d37859fc9ffcf0 Mon Sep 17 00:00:00 2001 From: Tonghao Zhang Date: Fri, 27 Apr 2018 08:19:43 -0700 Subject: [PATCH] vhost: fix dead lock on closing in server mode [ upstream commit 8b4b949144b80cc7312bbc189d38a3feaf2c74e5 ] When qemu close the unix socket fd of the vhostuser as a server, and then immediately delete the vhostuser port on openvswitch. There will be a deadlock. A thread (fdset event thread): B thread: 1. fdset_event_dispatch rte_vhost_driver_unregister 2. set the fd busy to 1. lock vsocket->conn_mutex 3. vhost_user_read_cb fdset_del waits busy changed to 0. 4. vhost peer closed, remove the conn from vsocket->conn_list: lock vsocket->conn_mutex 5. set the fd busy to 0 Fixes: 65388b43f592 ("vhost: fix fd leaks for vhost-user server mode") Signed-off-by: Tonghao Zhang Acked-by: Maxime Coquelin --- lib/librte_vhost/fd_man.c | 32 ++++++++++++++++++++++++++++++++ lib/librte_vhost/fd_man.h | 1 + lib/librte_vhost/socket.c | 14 +++++++++++++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/librte_vhost/fd_man.c b/lib/librte_vhost/fd_man.c index 181711c2a..7b209d274 100644 --- a/lib/librte_vhost/fd_man.c +++ b/lib/librte_vhost/fd_man.c @@ -171,6 +171,38 @@ fdset_del(struct fdset *pfdset, int fd) return dat; } +/** + * Unregister the fd from the fdset. + * + * If parameters are invalid, return directly -2. + * And check whether fd is busy, if yes, return -1. + * Otherwise, try to delete the fd from fdset and + * return true. + */ +int +fdset_try_del(struct fdset *pfdset, int fd) +{ + int i; + + if (pfdset == NULL || fd == -1) + return -2; + + pthread_mutex_lock(&pfdset->fd_mutex); + i = fdset_find_fd(pfdset, fd); + if (i != -1 && pfdset->fd[i].busy) { + pthread_mutex_unlock(&pfdset->fd_mutex); + return -1; + } + + if (i != -1) { + pfdset->fd[i].fd = -1; + pfdset->fd[i].rcb = pfdset->fd[i].wcb = NULL; + pfdset->fd[i].dat = NULL; + } + + pthread_mutex_unlock(&pfdset->fd_mutex); + return 0; +} /** * This functions runs in infinite blocking loop until there is no fd in diff --git a/lib/librte_vhost/fd_man.h b/lib/librte_vhost/fd_man.h index 3a9276c3c..57cf9ec4b 100644 --- a/lib/librte_vhost/fd_man.h +++ b/lib/librte_vhost/fd_man.h @@ -34,6 +34,7 @@ int fdset_add(struct fdset *pfdset, int fd, fd_cb rcb, fd_cb wcb, void *dat); void *fdset_del(struct fdset *pfdset, int fd); +int fdset_try_del(struct fdset *pfdset, int fd); void *fdset_event_dispatch(void *arg); diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c index 8fd47a4d8..5aa482fd4 100644 --- a/lib/librte_vhost/socket.c +++ b/lib/librte_vhost/socket.c @@ -756,13 +756,25 @@ rte_vhost_driver_unregister(const char *path) vhost_user_remove_reconnect(vsocket); } +again: 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); + /* + * If r/wcb is executing, release the + * conn_mutex lock, and try again since + * the r/wcb may use the conn_mutex lock. + */ + if (fdset_try_del(&vhost_user.fdset, + conn->connfd) == -1) { + pthread_mutex_unlock( + &vsocket->conn_mutex); + goto again; + } + RTE_LOG(INFO, VHOST_CONFIG, "free connfd = %d for device '%s'\n", conn->connfd, path); -- 2.14.2