lib/thread: Assert if spdk_put_io_channel() is called on the wrong thread

spdk_put_io_channel() was designed to be called on the same thread
that called spdk_get_io_channel(). spdk_put_io_channel() sends a
message to its own thread, to allow the context to unwind before
releasing the resources. This had the side effect to allow an
incorrect thread to call spdk_put_io_channel(). This patch will fix
that.

Bdevperf tool had a design flaw that needed the side effect, but
it was fixed recently.  We do not know if we have any other case.

Hence add assert to spdk_put_io_channel() to find other case.

We found that unit test for blobstore had called
spdk_put_io_channel() and fix it together in this patch.

Besides, correct the comment for spdk_put_io_channel() in
include/spdk/thread.h not to create any other case in future.

Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: I6ec7bf074818abef43b23ca40bc9385adac70a75
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/479390
Community-CI: SPDK CI Jenkins <sys_sgci@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Alexey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
Shuhei Matsumoto 2020-01-15 00:07:48 -05:00 committed by Jim Harris
parent 05e4366519
commit 655e8e16e3
3 changed files with 22 additions and 5 deletions

View File

@ -506,7 +506,7 @@ struct spdk_io_channel *spdk_get_io_channel(void *io_device);
/**
* Release a reference to an I/O channel. This happens asynchronously.
*
* Actual release will happen on the same thread that called spdk_get_io_channel()
* This must be called on the same thread that called spdk_get_io_channel()
* for the specified I/O channel. If this releases the last reference to the
* I/O channel, The destroy_cb function specified in spdk_io_device_register()
* will be invoked to release any associated resources.

View File

@ -1200,8 +1200,8 @@ _spdk_put_io_channel(void *arg)
}
SPDK_DEBUGLOG(SPDK_LOG_THREAD,
"Releasing io_channel %p for io_device %s (%p). Channel thread %p. Current thread %s\n",
ch, ch->dev->name, ch->dev->io_device, ch->thread, thread->name);
"Releasing io_channel %p for io_device %s (%p) on thread %s\n",
ch, ch->dev->name, ch->dev->io_device, thread->name);
assert(ch->thread == thread);
@ -1245,15 +1245,30 @@ _spdk_put_io_channel(void *arg)
void
spdk_put_io_channel(struct spdk_io_channel *ch)
{
struct spdk_thread *thread;
thread = spdk_get_thread();
if (!thread) {
SPDK_ERRLOG("called from non-SPDK thread\n");
assert(false);
return;
}
if (ch->thread != thread) {
SPDK_ERRLOG("different from the thread that called get_io_channel()\n");
assert(false);
return;
}
SPDK_DEBUGLOG(SPDK_LOG_THREAD,
"Putting io_channel %p for io_device %s (%p) on thread %s refcnt %u\n",
ch, ch->dev->name, ch->dev->io_device, ch->thread->name, ch->ref);
ch, ch->dev->name, ch->dev->io_device, thread->name, ch->ref);
ch->ref--;
if (ch->ref == 0) {
ch->destroy_ref++;
spdk_thread_send_msg(ch->thread, _spdk_put_io_channel, ch);
spdk_thread_send_msg(thread, _spdk_put_io_channel, ch);
}
}

View File

@ -4772,7 +4772,9 @@ blob_thin_prov_rw(void)
CU_ASSERT(g_bserrno == 0);
CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
set_thread(1);
spdk_bs_free_io_channel(channel_thread1);
set_thread(0);
spdk_bs_free_io_channel(channel);
poll_threads();