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 <dariuszx.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/371175
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Pawel Wodkowski <pawelx.wodkowski@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Dariusz Stojaczyk 2017-07-25 20:40:17 +02:00 committed by Daniel Verkamp
parent 10b1a4a9a3
commit 9291b2e0d7

View File

@ -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 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) 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; struct rte_vhost_vring *q;
uint16_t i; uint16_t i;
pthread_mutex_lock(&g_spdk_vhost_mutex);
vdev = spdk_vhost_dev_find_by_vid(vid); vdev = spdk_vhost_dev_find_by_vid(vid);
if (vdev == NULL) { if (vdev == NULL) {
SPDK_ERRLOG("Couldn't find device with vid %d to stop.\n", vid); SPDK_ERRLOG("Couldn't find device with vid %d to stop.\n", vid);
pthread_mutex_unlock(&g_spdk_vhost_mutex);
return; return;
} }
if (vdev->backend->destroy_device(vdev) != 0) { if (vdev->backend->destroy_device(vdev) != 0) {
SPDK_ERRLOG("Couldn't stop device with vid %d.\n", vid); SPDK_ERRLOG("Couldn't stop device with vid %d.\n", vid);
pthread_mutex_unlock(&g_spdk_vhost_mutex);
return; return;
} }
@ -554,6 +558,7 @@ destroy_device(int vid)
spdk_vhost_free_reactor(vdev->lcore); spdk_vhost_free_reactor(vdev->lcore);
vdev->lcore = -1; vdev->lcore = -1;
vdev->vid = -1; vdev->vid = -1;
pthread_mutex_unlock(&g_spdk_vhost_mutex);
} }
static int static int
@ -561,43 +566,45 @@ new_device(int vid)
{ {
struct spdk_vhost_dev *vdev; struct spdk_vhost_dev *vdev;
char ifname[PATH_MAX]; char ifname[PATH_MAX];
int rc; int rc = -1;
uint16_t num_queues;
uint16_t num_queues = rte_vhost_get_vring_num(vid);
uint16_t i; 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) { if (rte_vhost_get_ifname(vid, ifname, PATH_MAX) < 0) {
SPDK_ERRLOG("Couldn't get a valid ifname for device %d\n", vid); SPDK_ERRLOG("Couldn't get a valid ifname for device %d\n", vid);
return -1; goto out;
} }
vdev = spdk_vhost_dev_find(ifname); vdev = spdk_vhost_dev_find(ifname);
if (vdev == NULL) { if (vdev == NULL) {
SPDK_ERRLOG("Controller %s not found.\n", ifname); SPDK_ERRLOG("Controller %s not found.\n", ifname);
return -1; goto out;
} }
if (vdev->lcore != -1) { if (vdev->lcore != -1) {
SPDK_ERRLOG("Controller %s already connected.\n", ifname); SPDK_ERRLOG("Controller %s already connected.\n", ifname);
return -1; goto out;
} }
if (num_queues > SPDK_VHOST_MAX_VQUEUES) { if (num_queues > SPDK_VHOST_MAX_VQUEUES) {
SPDK_ERRLOG("vhost device %d: Too many queues (%"PRIu16"). Max %"PRIu16"\n", vid, num_queues, SPDK_ERRLOG("vhost device %d: Too many queues (%"PRIu16"). Max %"PRIu16"\n", vid, num_queues,
SPDK_VHOST_MAX_VQUEUES); SPDK_VHOST_MAX_VQUEUES);
return -1; goto out;
} }
for (i = 0; i < num_queues; i++) { for (i = 0; i < num_queues; i++) {
if (rte_vhost_get_vhost_vring(vid, i, &vdev->virtqueue[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); SPDK_ERRLOG("vhost device %d: Failed to get information of queue %"PRIu16"\n", vid, i);
return -1; goto out;
} }
/* Disable notifications. */ /* Disable notifications. */
if (rte_vhost_enable_guest_notification(vid, i, 0) != 0) { 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); 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) { if (rte_vhost_get_negotiated_features(vid, &vdev->negotiated_features) != 0) {
SPDK_ERRLOG("vhost device %d: Failed to get negotiated driver features\n", vid); 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) { if (rte_vhost_get_mem_table(vid, &vdev->mem) != 0) {
SPDK_ERRLOG("vhost device %d: Failed to get guest memory table\n", vid); 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); vdev->lcore = spdk_vhost_allocate_reactor(vdev->cpumask);
@ -622,10 +629,11 @@ new_device(int vid)
spdk_vhost_free_reactor(vdev->lcore); spdk_vhost_free_reactor(vdev->lcore);
vdev->lcore = -1; vdev->lcore = -1;
vdev->vid = -1; vdev->vid = -1;
return -1;
} }
return 0; out:
pthread_mutex_unlock(&g_spdk_vhost_mutex);
return rc;
} }
void void