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_create_cb create_cb;
|
||||||
spdk_io_channel_destroy_cb destroy_cb;
|
spdk_io_channel_destroy_cb destroy_cb;
|
||||||
spdk_io_device_unregister_cb unregister_cb;
|
spdk_io_device_unregister_cb unregister_cb;
|
||||||
|
struct spdk_thread *unregister_thread;
|
||||||
uint32_t ctx_size;
|
uint32_t ctx_size;
|
||||||
uint32_t for_each_count;
|
uint32_t for_each_count;
|
||||||
TAILQ_ENTRY(io_device) tailq;
|
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);
|
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
|
static void
|
||||||
_spdk_io_device_attempt_free(struct io_device *dev, struct spdk_io_channel *ch)
|
_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);
|
pthread_mutex_unlock(&g_devlist_mutex);
|
||||||
|
|
||||||
if (dev->unregister_cb) {
|
if (dev->unregister_cb == NULL) {
|
||||||
dev->unregister_cb(dev->io_device);
|
free(dev);
|
||||||
|
} else {
|
||||||
|
assert(dev->unregister_thread != NULL);
|
||||||
|
spdk_thread_send_msg(dev->unregister_thread, _finish_unregister, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -393,6 +404,7 @@ spdk_io_device_unregister(void *io_device, spdk_io_device_unregister_cb unregist
|
|||||||
dev->unregistered = true;
|
dev->unregistered = true;
|
||||||
TAILQ_REMOVE(&g_io_devices, dev, tailq);
|
TAILQ_REMOVE(&g_io_devices, dev, tailq);
|
||||||
pthread_mutex_unlock(&g_devlist_mutex);
|
pthread_mutex_unlock(&g_devlist_mutex);
|
||||||
|
dev->unregister_thread = spdk_get_thread();
|
||||||
_spdk_io_device_attempt_free(dev, NULL);
|
_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 const char *g_check_version_msg;
|
||||||
static bool g_pmemblk_open_allow_open = true;
|
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_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_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);
|
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 */
|
/* Unload module to free IO channel */
|
||||||
g_bdev_pmem_module->module_fini();
|
g_bdev_pmem_module->module_fini();
|
||||||
|
|
||||||
|
spdk_free_thread();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,6 +376,8 @@ ut_pmem_blk_init(void)
|
|||||||
{
|
{
|
||||||
errno = 0;
|
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);
|
g_pool_ok.buffer = calloc(g_pool_ok.nblock, g_pool_ok.bsize);
|
||||||
if (g_pool_ok.buffer == NULL) {
|
if (g_pool_ok.buffer == NULL) {
|
||||||
ut_pmem_blk_clean();
|
ut_pmem_blk_clean();
|
||||||
|
Loading…
Reference in New Issue
Block a user