io_channel: invoke unregister_cb on same thread unregister was called
The unregister callback is only invoked after all I/O channels related to the I/O device have been freed. The last I/O channel to be freed might be on a thread different than the thread where spdk_io_device_unregister was called. If this is the case, send an event to the latter thread so that the callback gets called on the same thread as spdk_io_device_unregister. Signed-off-by: Jim Harris <james.r.harris@intel.com> Change-Id: I3c910198fbd83eae95e5c57d618284e64db46ff7 Reviewed-on: https://review.gerrithub.io/404414 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
parent
1b41df0558
commit
a8d3ac0cf4
@ -51,6 +51,7 @@ struct io_device {
|
||||
spdk_io_channel_create_cb create_cb;
|
||||
spdk_io_channel_destroy_cb destroy_cb;
|
||||
spdk_io_device_unregister_cb unregister_cb;
|
||||
struct spdk_thread *unregister_thread;
|
||||
uint32_t ctx_size;
|
||||
uint32_t for_each_count;
|
||||
TAILQ_ENTRY(io_device) tailq;
|
||||
@ -327,6 +328,15 @@ spdk_io_device_register(void *io_device, spdk_io_channel_create_cb create_cb,
|
||||
pthread_mutex_unlock(&g_devlist_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
_finish_unregister(void *arg)
|
||||
{
|
||||
struct io_device *dev = arg;
|
||||
|
||||
dev->unregister_cb(dev->io_device);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
_spdk_io_device_attempt_free(struct io_device *dev, struct spdk_io_channel *ch)
|
||||
{
|
||||
@ -358,11 +368,12 @@ _spdk_io_device_attempt_free(struct io_device *dev, struct spdk_io_channel *ch)
|
||||
}
|
||||
pthread_mutex_unlock(&g_devlist_mutex);
|
||||
|
||||
if (dev->unregister_cb) {
|
||||
dev->unregister_cb(dev->io_device);
|
||||
if (dev->unregister_cb == NULL) {
|
||||
free(dev);
|
||||
} else {
|
||||
assert(dev->unregister_thread != NULL);
|
||||
spdk_thread_send_msg(dev->unregister_thread, _finish_unregister, dev);
|
||||
}
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
void
|
||||
@ -393,6 +404,7 @@ spdk_io_device_unregister(void *io_device, spdk_io_device_unregister_cb unregist
|
||||
dev->unregistered = true;
|
||||
TAILQ_REMOVE(&g_io_devices, dev, tailq);
|
||||
pthread_mutex_unlock(&g_devlist_mutex);
|
||||
dev->unregister_thread = spdk_get_thread();
|
||||
_spdk_io_device_attempt_free(dev, NULL);
|
||||
}
|
||||
|
||||
|
@ -90,6 +90,12 @@ static struct spdk_bdev *g_bdev;
|
||||
static const char *g_check_version_msg;
|
||||
static bool g_pmemblk_open_allow_open = true;
|
||||
|
||||
static void
|
||||
_pmem_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx)
|
||||
{
|
||||
fn(ctx);
|
||||
}
|
||||
|
||||
DEFINE_STUB(spdk_json_write_object_begin, int, (struct spdk_json_write_ctx *w), 0);
|
||||
DEFINE_STUB(spdk_json_write_object_end, int, (struct spdk_json_write_ctx *w), 0);
|
||||
DEFINE_STUB(spdk_json_write_string, int, (struct spdk_json_write_ctx *w, const char *val), 0);
|
||||
@ -359,6 +365,9 @@ ut_pmem_blk_clean(void)
|
||||
|
||||
/* Unload module to free IO channel */
|
||||
g_bdev_pmem_module->module_fini();
|
||||
|
||||
spdk_free_thread();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -367,6 +376,8 @@ ut_pmem_blk_init(void)
|
||||
{
|
||||
errno = 0;
|
||||
|
||||
spdk_allocate_thread(_pmem_send_msg, NULL, NULL, NULL, NULL);
|
||||
|
||||
g_pool_ok.buffer = calloc(g_pool_ok.nblock, g_pool_ok.bsize);
|
||||
if (g_pool_ok.buffer == NULL) {
|
||||
ut_pmem_blk_clean();
|
||||
|
Loading…
Reference in New Issue
Block a user