From 9291b2e0d7242ccfc8e2776dd489ae8817a97664 Mon Sep 17 00:00:00 2001 From: Dariusz Stojaczyk Date: Tue, 25 Jul 2017 20:40:17 +0200 Subject: [PATCH] vhost: added generic vhost mutex Added mutex to synchronize vdev access from external threads. This is the next step towards fixing synchronization issues between vhost reactor, RPC, and DPDK. Change-Id: Id4b52658e05d02c479618ae0e5b5e58af2f02789 Signed-off-by: Dariusz Stojaczyk Reviewed-on: https://review.gerrithub.io/371175 Tested-by: SPDK Automated Test System Reviewed-by: Pawel Wodkowski Reviewed-by: Daniel Verkamp --- lib/vhost/vhost.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c index 7b4a027a9..ba7824897 100644 --- a/lib/vhost/vhost.c +++ b/lib/vhost/vhost.c @@ -59,6 +59,7 @@ const struct vhost_device_ops g_spdk_vhost_ops = { }; static struct spdk_vhost_dev *g_spdk_vhost_devices[MAX_VHOST_DEVICES]; +static pthread_mutex_t g_spdk_vhost_mutex = PTHREAD_MUTEX_INITIALIZER; void *spdk_vhost_gpa_to_vva(struct spdk_vhost_dev *vdev, uint64_t addr) { @@ -534,14 +535,17 @@ destroy_device(int vid) struct rte_vhost_vring *q; uint16_t i; + pthread_mutex_lock(&g_spdk_vhost_mutex); vdev = spdk_vhost_dev_find_by_vid(vid); if (vdev == NULL) { SPDK_ERRLOG("Couldn't find device with vid %d to stop.\n", vid); + pthread_mutex_unlock(&g_spdk_vhost_mutex); return; } if (vdev->backend->destroy_device(vdev) != 0) { SPDK_ERRLOG("Couldn't stop device with vid %d.\n", vid); + pthread_mutex_unlock(&g_spdk_vhost_mutex); return; } @@ -554,6 +558,7 @@ destroy_device(int vid) spdk_vhost_free_reactor(vdev->lcore); vdev->lcore = -1; vdev->vid = -1; + pthread_mutex_unlock(&g_spdk_vhost_mutex); } static int @@ -561,43 +566,45 @@ new_device(int vid) { struct spdk_vhost_dev *vdev; char ifname[PATH_MAX]; - int rc; - - uint16_t num_queues = rte_vhost_get_vring_num(vid); + int rc = -1; + uint16_t num_queues; uint16_t i; + pthread_mutex_lock(&g_spdk_vhost_mutex); + num_queues = rte_vhost_get_vring_num(vid); + if (rte_vhost_get_ifname(vid, ifname, PATH_MAX) < 0) { SPDK_ERRLOG("Couldn't get a valid ifname for device %d\n", vid); - return -1; + goto out; } vdev = spdk_vhost_dev_find(ifname); if (vdev == NULL) { SPDK_ERRLOG("Controller %s not found.\n", ifname); - return -1; + goto out; } if (vdev->lcore != -1) { SPDK_ERRLOG("Controller %s already connected.\n", ifname); - return -1; + goto out; } if (num_queues > SPDK_VHOST_MAX_VQUEUES) { SPDK_ERRLOG("vhost device %d: Too many queues (%"PRIu16"). Max %"PRIu16"\n", vid, num_queues, SPDK_VHOST_MAX_VQUEUES); - return -1; + goto out; } for (i = 0; i < num_queues; i++) { if (rte_vhost_get_vhost_vring(vid, i, &vdev->virtqueue[i])) { SPDK_ERRLOG("vhost device %d: Failed to get information of queue %"PRIu16"\n", vid, i); - return -1; + goto out; } /* Disable notifications. */ if (rte_vhost_enable_guest_notification(vid, i, 0) != 0) { SPDK_ERRLOG("vhost device %d: Failed to disable guest notification on queue %"PRIu16"\n", vid, i); - return -1; + goto out; } } @@ -607,12 +614,12 @@ new_device(int vid) if (rte_vhost_get_negotiated_features(vid, &vdev->negotiated_features) != 0) { SPDK_ERRLOG("vhost device %d: Failed to get negotiated driver features\n", vid); - return -1; + goto out; } if (rte_vhost_get_mem_table(vid, &vdev->mem) != 0) { SPDK_ERRLOG("vhost device %d: Failed to get guest memory table\n", vid); - return -1; + goto out; } vdev->lcore = spdk_vhost_allocate_reactor(vdev->cpumask); @@ -622,10 +629,11 @@ new_device(int vid) spdk_vhost_free_reactor(vdev->lcore); vdev->lcore = -1; vdev->vid = -1; - return -1; } - return 0; +out: + pthread_mutex_unlock(&g_spdk_vhost_mutex); + return rc; } void