Commit 399a38a5 authored by Ben Walker's avatar Ben Walker Committed by Jim Harris
Browse files

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: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.gerrithub.io/424141


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
parent c9402000
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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;

+5 −1
Original line number Diff line number Diff line
@@ -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);
	}
}