From 399a38a5417662bff39b0896e20d72d76ad8fcf9 Mon Sep 17 00:00:00 2001 From: Ben Walker Date: Thu, 30 Aug 2018 15:55:22 -0700 Subject: [PATCH] thread: Fix issue where a channel would be destroyed twice The scenario is as follows: spdk_get_io_channel(...) spdk_put_io_channel(...) <- sends a message to do the release spdk_get_io_channel(...) spdk_put_io_channel(...) <- sends a message to do the release again _spdk_put_io_channel(...) _spdk_put_io_channel(...) <- boom Change-Id: I86a66c68a525964e0d2dcd9cac2c292dc8b43136 Signed-off-by: Ben Walker Reviewed-on: https://review.gerrithub.io/424141 Tested-by: SPDK CI Jenkins Chandler-Test-Pool: SPDK Automated Test System Reviewed-by: Changpeng Liu Reviewed-by: Jim Harris Reviewed-by: Shuhei Matsumoto --- include/spdk/thread.h | 1 + lib/thread/thread.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/spdk/thread.h b/include/spdk/thread.h index 00590e4fd..63cb7b31b 100644 --- a/include/spdk/thread.h +++ b/include/spdk/thread.h @@ -151,6 +151,7 @@ struct spdk_io_channel { struct spdk_thread *thread; struct io_device *dev; uint32_t ref; + uint32_t destroy_ref; TAILQ_ENTRY(spdk_io_channel) tailq; spdk_io_channel_destroy_cb destroy_cb; diff --git a/lib/thread/thread.c b/lib/thread/thread.c index bf484ccee..7c91cac94 100644 --- a/lib/thread/thread.c +++ b/lib/thread/thread.c @@ -519,6 +519,7 @@ spdk_get_io_channel(void *io_device) ch->destroy_cb = dev->destroy_cb; ch->thread = thread; ch->ref = 1; + ch->destroy_ref = 0; TAILQ_INSERT_TAIL(&thread->io_channels, ch, tailq); SPDK_DEBUGLOG(SPDK_LOG_THREAD, "Get io_channel %p for io_device %s (%p) on thread %s refcnt %u\n", @@ -553,7 +554,9 @@ _spdk_put_io_channel(void *arg) assert(ch->thread == spdk_get_thread()); - if (ch->ref > 0) { + ch->destroy_ref--; + + if (ch->ref > 0 || ch->destroy_ref > 0) { /* * Another reference to the associated io_device was requested * after this message was sent but before it had a chance to @@ -598,6 +601,7 @@ spdk_put_io_channel(struct spdk_io_channel *ch) ch->ref--; if (ch->ref == 0) { + ch->destroy_ref++; spdk_thread_send_msg(ch->thread, _spdk_put_io_channel, ch); } }