From patchwork Thu Mar 12 09:57:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?546L5b+X5YWL?= X-Patchwork-Id: 66574 X-Patchwork-Delegate: maxime.coquelin@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 1240DA0569; Thu, 12 Mar 2020 10:57:53 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id D9CE31C010; Thu, 12 Mar 2020 10:57:52 +0100 (CET) Received: from m12-18.163.com (m12-18.163.com [220.181.12.18]) by dpdk.org (Postfix) with ESMTP id 705412BAA; Thu, 12 Mar 2020 10:57:47 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:Subject:Date:Message-Id; bh=7LZhwOo9SeoWLJAyaF NOBMegWmfjJLAjzzsCnHaW3oQ=; b=FkU2t+uKdIh98XDMu+VLVJwpzlnmGv0JLZ v+M8+kijrsbc8a+i5zFVoc5hoigTjSlFjjRf/VsydeUT6Mef0FMMPhV+DusG6qvX wZC+ObZtGMROnd74siXTZx9TtLwS6zBuUFjouB4fSwXLIDXOh5PZW9AY4uYzBjkD B9NpWYSxM= Received: from localhost.localdomain (unknown [106.38.115.15]) by smtp14 (Coremail) with SMTP id EsCowAAnndmOB2peVunzBA--.43447S2; Thu, 12 Mar 2020 17:57:46 +0800 (CST) From: Zhike Wang To: dev@dpdk.org Cc: maxime.coquelin@redhat.com, xiaolong.ye@intel.com, zhihong.wang@intel.com, stable@dpdk.org, Zhike Wang Date: Thu, 12 Mar 2020 17:57:19 +0800 Message-Id: <1584007039-12437-1-git-send-email-wangzhike@jd.com> X-Mailer: git-send-email 1.8.3.1 X-CM-TRANSID: EsCowAAnndmOB2peVunzBA--.43447S2 X-Coremail-Antispam: 1Uf129KBjvJXoWxAry7Xw4UWF45Xw18Zw45GFg_yoW5XFWfpa 45WFy3JrZ7Gr10vrsrA3WrG34rKF1rAF47u3s7K3WUZrWUCw4Yqa92ka4jgw13JFy8ZF4U AF4Iga9Y9r18Cw7anT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07jVmhrUUUUU= X-Originating-IP: [106.38.115.15] X-CM-SenderInfo: pzdqw6bntsiqqrwthudrp/1tbiVhrkulqzkD-S4AAAsm Subject: [dpdk-dev] [PATCH] vhost: return -EAGAIN during unregistering vhost if it is busy. X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The vhost_user_read_cb() and rte_vhost_driver_unregister() can be called at the same time by 2 threads, and may lead to deadlock. Eg thread1 calls vhost_user_read_cb()->vhost_user_get_vring_base()->destroy_device(), then thread2 calls rte_vhost_driver_unregister(), and will retry the fdset_try_del() in loop. Some application implements destroy_device() as a blocking function, eg OVS calls ovsrcu_synchronize() insides destroy_device(). As a result, thread1(eg vhost_events) is blocked to wait quiesce of thread2(eg ovs-vswitchd), and thread2 is in a loop to wait thread1 to give up the use of the vhost fd, then leads to deadlock. It is better to return -EAGAIN to application, who will decide how to handle (eg OVS can call ovsrcu_quiesce() and then retry). Signed-off-by: Zhike Wang --- lib/librte_vhost/rte_vhost.h | 4 +++- lib/librte_vhost/socket.c | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h index c7b619a..276db11 100644 --- a/lib/librte_vhost/rte_vhost.h +++ b/lib/librte_vhost/rte_vhost.h @@ -389,7 +389,9 @@ void rte_vhost_log_used_vring(int vid, uint16_t vring_idx, */ int rte_vhost_driver_register(const char *path, uint64_t flags); -/* Unregister vhost driver. This is only meaningful to vhost user. */ +/* Unregister vhost driver. This is only meaningful to vhost user. + * Return -EAGAIN if device is busy, and leave it to be handled by application. + */ int rte_vhost_driver_unregister(const char *path); /** diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c index 7c80121..a75a3f6 100644 --- a/lib/librte_vhost/socket.c +++ b/lib/librte_vhost/socket.c @@ -1027,7 +1027,8 @@ struct vhost_user_reconnect_list { } /** - * Unregister the specified vhost socket + * Unregister the specified vhost socket. + * Return -EAGAIN if device is busy, and leave it to be handled by application. */ int rte_vhost_driver_unregister(const char *path) @@ -1039,7 +1040,6 @@ struct vhost_user_reconnect_list { if (path == NULL) return -1; -again: pthread_mutex_lock(&vhost_user.mutex); for (i = 0; i < vhost_user.vsocket_cnt; i++) { @@ -1063,7 +1063,7 @@ struct vhost_user_reconnect_list { pthread_mutex_unlock( &vsocket->conn_mutex); pthread_mutex_unlock(&vhost_user.mutex); - goto again; + return -EAGAIN; } VHOST_LOG_CONFIG(INFO, @@ -1085,7 +1085,7 @@ struct vhost_user_reconnect_list { if (fdset_try_del(&vhost_user.fdset, vsocket->socket_fd) == -1) { pthread_mutex_unlock(&vhost_user.mutex); - goto again; + return -EAGAIN; } close(vsocket->socket_fd);