From 9aed854be08215eb96edeff897e8a25a2858dc78 Mon Sep 17 00:00:00 2001 From: GangCao Date: Sun, 4 Feb 2018 15:39:55 -0500 Subject: [PATCH] bdev: add a common channel resource destroy function In the different cases to creat a bdev channel, added a common cleanup function to destroy the resource. The same function is also called at the bdev channel destruction. Change-Id: I81b60cab9df3a8975b0a9982482c9d27899d8a79 Signed-off-by: GangCao Reviewed-on: https://review.gerrithub.io/398351 Tested-by: SPDK Automated Test System Reviewed-by: Reviewed-by: Jim Harris --- lib/bdev/bdev.c | 44 ++++++++++++++++++-------- test/unit/lib/bdev/mt/bdev.c/bdev_ut.c | 24 +++++++++++++- 2 files changed, 53 insertions(+), 15 deletions(-) diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index 25b4c082b2..e69ad8f335 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -869,6 +869,31 @@ spdk_bdev_dump_config_json(struct spdk_bdev *bdev, struct spdk_json_write_ctx *w return 0; } +static void +_spdk_bdev_channel_destroy_resource(struct spdk_bdev_channel *ch) +{ + struct spdk_bdev_mgmt_channel *mgmt_channel; + struct spdk_bdev_module_channel *shared_ch = ch->module_ch; + + if (ch->channel) { + spdk_put_io_channel(ch->channel); + } + + if (ch->mgmt_channel) { + if (shared_ch) { + assert(shared_ch->ref > 0); + shared_ch->ref--; + if (shared_ch->ref == 0) { + mgmt_channel = spdk_io_channel_get_ctx(ch->mgmt_channel); + assert(shared_ch->io_outstanding == 0); + TAILQ_REMOVE(&mgmt_channel->module_channels, shared_ch, link); + free(shared_ch); + } + } + spdk_put_io_channel(ch->mgmt_channel); + } +} + static int spdk_bdev_channel_create(void *io_device, void *ctx_buf) { @@ -880,12 +905,13 @@ spdk_bdev_channel_create(void *io_device, void *ctx_buf) ch->bdev = io_device; ch->channel = bdev->fn_table->get_io_channel(bdev->ctxt); if (!ch->channel) { + _spdk_bdev_channel_destroy_resource(ch); return -1; } ch->mgmt_channel = spdk_get_io_channel(&g_bdev_mgr); if (!ch->mgmt_channel) { - spdk_put_io_channel(ch->channel); + _spdk_bdev_channel_destroy_resource(ch); return -1; } @@ -900,8 +926,7 @@ spdk_bdev_channel_create(void *io_device, void *ctx_buf) if (shared_ch == NULL) { shared_ch = calloc(1, sizeof(*shared_ch)); if (!shared_ch) { - spdk_put_io_channel(ch->channel); - spdk_put_io_channel(ch->mgmt_channel); + _spdk_bdev_channel_destroy_resource(ch); return -1; } @@ -924,8 +949,7 @@ spdk_bdev_channel_create(void *io_device, void *ctx_buf) __itt_init_ittlib(NULL, 0); name = spdk_sprintf_alloc("spdk_bdev_%s_%p", ch->bdev->name, ch); if (!name) { - spdk_put_io_channel(ch->channel); - spdk_put_io_channel(ch->mgmt_channel); + _spdk_bdev_channel_destroy_resource(ch); return -1; } ch->handle = __itt_string_handle_create(name); @@ -1003,15 +1027,7 @@ spdk_bdev_channel_destroy(void *io_device, void *ctx_buf) _spdk_bdev_abort_buf_io(&mgmt_channel->need_buf_small, ch); _spdk_bdev_abort_buf_io(&mgmt_channel->need_buf_large, ch); - assert(shared_ch->ref > 0); - shared_ch->ref--; - if (shared_ch->ref == 0) { - assert(shared_ch->io_outstanding == 0); - TAILQ_REMOVE(&mgmt_channel->module_channels, shared_ch, link); - free(shared_ch); - } - spdk_put_io_channel(ch->channel); - spdk_put_io_channel(ch->mgmt_channel); + _spdk_bdev_channel_destroy_resource(ch); } int diff --git a/test/unit/lib/bdev/mt/bdev.c/bdev_ut.c b/test/unit/lib/bdev/mt/bdev.c/bdev_ut.c index 8f4b04dd17..ef93030055 100644 --- a/test/unit/lib/bdev/mt/bdev.c/bdev_ut.c +++ b/test/unit/lib/bdev/mt/bdev.c/bdev_ut.c @@ -61,12 +61,18 @@ int g_io_device; struct ut_bdev g_bdev; struct spdk_bdev_desc *g_desc; bool g_teardown_done = false; +bool g_get_io_channel = true; +bool g_create_ch = true; static int stub_create_ch(void *io_device, void *ctx_buf) { struct ut_bdev_channel *ch = ctx_buf; + if (g_create_ch == false) { + return -1; + } + TAILQ_INIT(&ch->outstanding_io); ch->outstanding_cnt = 0; /* @@ -89,7 +95,11 @@ stub_get_io_channel(void *ctx) { struct ut_bdev *ut_bdev = ctx; - return spdk_get_io_channel(ut_bdev->io_target); + if (g_get_io_channel == true) { + return spdk_get_io_channel(ut_bdev->io_target); + } else { + return NULL; + } } static int @@ -241,7 +251,19 @@ basic(void) set_thread(0); + g_get_io_channel = false; g_ut_threads[0].ch = spdk_bdev_get_io_channel(g_desc); + CU_ASSERT(g_ut_threads[0].ch == NULL); + + g_get_io_channel = true; + g_create_ch = false; + g_ut_threads[0].ch = spdk_bdev_get_io_channel(g_desc); + CU_ASSERT(g_ut_threads[0].ch == NULL); + + g_get_io_channel = true; + g_create_ch = true; + g_ut_threads[0].ch = spdk_bdev_get_io_channel(g_desc); + CU_ASSERT(g_ut_threads[0].ch != NULL); spdk_put_io_channel(g_ut_threads[0].ch); teardown_test();