vhost: use trylock inside async events body

This makes the async event body non-blocking
and also fixes potential deadlock scenario:
 * call_external_event() enqueues vhost_event
 * destroy_device() locks g_spdk_vhost_mutex
 * destroy_device() enqueues it's vhost_event
 * reactor dequeues events
  * cb from call_external_event is dequeued first
    * g_spdk_vhost_mutex is locked (deadlock)
 * destroy_device() times out, abort()

Change-Id: If8f51ada3ee5c47ba126f74187a40a285c001c77
Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/380634
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Dariusz Stojaczyk 2017-09-28 17:43:02 +02:00 committed by Jim Harris
parent d565f549b9
commit d4e19ecc1c
2 changed files with 8 additions and 1 deletions

View File

@ -561,8 +561,14 @@ spdk_vhost_event_async_fn(void *arg1, void *arg2)
{
struct spdk_vhost_dev_event_ctx *ctx = arg1;
struct spdk_vhost_dev *vdev;
struct spdk_event *ev;
if (pthread_mutex_trylock(&g_spdk_vhost_mutex) != 0) {
ev = spdk_event_allocate(spdk_env_get_current_core(), spdk_vhost_event_async_fn, arg1, arg2);
spdk_event_call(ev);
return;
}
pthread_mutex_lock(&g_spdk_vhost_mutex);
vdev = spdk_vhost_dev_find(ctx->ctrlr_name);
if (vdev != ctx->vdev) {
/* vdev has been changed after enqueuing this event */

View File

@ -67,6 +67,7 @@ DEFINE_STUB(spdk_vhost_scsi_controller_construct, int, (void), 0);
DEFINE_STUB(spdk_vhost_blk_controller_construct, int, (void), 0);
DEFINE_STUB(rte_vhost_set_vhost_vring_last_idx, int,
(int vid, uint16_t vring_idx, uint16_t last_avail_idx, uint16_t last_used_idx), 0);
DEFINE_STUB(spdk_env_get_current_core, uint32_t, (void), 0);
static int
test_setup(void)