From patchwork Wed Sep 5 04:28:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tiwei Bie X-Patchwork-Id: 44290 X-Patchwork-Delegate: maxime.coquelin@redhat.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 441E52C4F; Wed, 5 Sep 2018 06:31:05 +0200 (CEST) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by dpdk.org (Postfix) with ESMTP id 3381C28FD; Wed, 5 Sep 2018 06:31:02 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 04 Sep 2018 21:31:00 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,332,1531810800"; d="scan'208";a="68456347" Received: from btwcube1.sh.intel.com ([10.67.104.194]) by fmsmga008.fm.intel.com with ESMTP; 04 Sep 2018 21:29:47 -0700 From: Tiwei Bie To: maxime.coquelin@redhat.com, zhihong.wang@intel.com, dev@dpdk.org Cc: seanbh@gmail.com, anatoly.burakov@intel.com, stable@dpdk.org Date: Wed, 5 Sep 2018 12:28:50 +0800 Message-Id: <20180905042852.6212-2-tiwei.bie@intel.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180905042852.6212-1-tiwei.bie@intel.com> References: <20180905042852.6212-1-tiwei.bie@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 1/3] net/virtio-user: fix deadlock in memory events callback 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" Deadlock can occur when allocating memory if a vhost-kernel based virtio-user device is in use. To fix the deadlock, we will take memory hotplug lock explicitly in virtio-user when necessary, and always call the _thread_unsafe memory functions. Bugzilla ID: 81 Fixes: 12ecb2f63b12 ("net/virtio-user: support memory hotplug") Cc: stable@dpdk.org Reported-by: Seán Harte Signed-off-by: Tiwei Bie Tested-by: Seán Harte Reviewed-by: Seán Harte Reviewed-by: Anatoly Burakov Reviewed-by: Maxime Coquelin --- drivers/net/virtio/virtio_user/vhost_kernel.c | 6 +++++- .../net/virtio/virtio_user/virtio_user_dev.c | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c b/drivers/net/virtio/virtio_user/vhost_kernel.c index b2444096c..897fee0af 100644 --- a/drivers/net/virtio/virtio_user/vhost_kernel.c +++ b/drivers/net/virtio/virtio_user/vhost_kernel.c @@ -115,7 +115,11 @@ prepare_vhost_memory_kernel(void) wa.region_nr = 0; wa.vm = vm; - if (rte_memseg_contig_walk(add_memory_region, &wa) < 0) { + /* + * The memory lock has already been taken by memory subsystem + * or virtio_user_start_device(). + */ + if (rte_memseg_contig_walk_thread_unsafe(add_memory_region, &wa) < 0) { free(vm); return NULL; } diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c index 7df600b02..869e96f87 100644 --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c @@ -13,6 +13,8 @@ #include #include +#include + #include "vhost.h" #include "virtio_user_dev.h" #include "../virtio_ethdev.h" @@ -109,9 +111,24 @@ is_vhost_user_by_type(const char *path) int virtio_user_start_device(struct virtio_user_dev *dev) { + struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; uint64_t features; int ret; + /* + * XXX workaround! + * + * We need to make sure that the locks will be + * taken in the correct order to avoid deadlocks. + * + * Before releasing this lock, this thread should + * not trigger any memory hotplug events. + * + * This is a temporary workaround, and should be + * replaced when we get proper supports from the + * memory subsystem in the future. + */ + rte_rwlock_read_lock(&mcfg->memory_hotplug_lock); pthread_mutex_lock(&dev->mutex); if (is_vhost_user_by_type(dev->path) && dev->vhostfd < 0) @@ -152,10 +169,12 @@ virtio_user_start_device(struct virtio_user_dev *dev) dev->started = true; pthread_mutex_unlock(&dev->mutex); + rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock); return 0; error: pthread_mutex_unlock(&dev->mutex); + rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock); /* TODO: free resource here or caller to check */ return -1; }