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 <benjamin.walker@intel.com>
Reviewed-on: https://review.gerrithub.io/424141
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Ben Walker 2018-08-30 15:55:22 -07:00 committed by Jim Harris
parent c94020001a
commit 399a38a541
2 changed files with 6 additions and 1 deletions

View File

@ -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;

View File

@ -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);
}
}