From d4e19ecc1cceae731cc5891e25436565f10f2eb2 Mon Sep 17 00:00:00 2001 From: Dariusz Stojaczyk Date: Thu, 28 Sep 2017 17:43:02 +0200 Subject: [PATCH] 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 Reviewed-on: https://review.gerrithub.io/380634 Tested-by: SPDK Automated Test System Reviewed-by: Jim Harris Reviewed-by: Daniel Verkamp --- lib/vhost/vhost.c | 8 +++++++- test/unit/lib/vhost/vhost.c/vhost_ut.c | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c index c1f926b34..26c925f92 100644 --- a/lib/vhost/vhost.c +++ b/lib/vhost/vhost.c @@ -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 */ diff --git a/test/unit/lib/vhost/vhost.c/vhost_ut.c b/test/unit/lib/vhost/vhost.c/vhost_ut.c index f7d212eeb..b7162f43a 100644 --- a/test/unit/lib/vhost/vhost.c/vhost_ut.c +++ b/test/unit/lib/vhost/vhost.c/vhost_ut.c @@ -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)