From 32aa4fa0a35ee006eadb2969665d794cf87c5a23 Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Tue, 27 Sep 2016 13:22:15 -0700 Subject: [PATCH] util: add context parameter for unique I/O channels Signed-off-by: Jim Harris Change-Id: I296992b2e03b9b516cfd26726405e49616ad08a5 --- include/spdk/io_channel.h | 9 ++++++-- lib/bdev/aio/blockdev_aio.c | 4 ++-- lib/bdev/nvme/blockdev_nvme.c | 4 ++-- lib/copy/copy_engine.c | 8 +++---- lib/copy/ioat/copy_engine_ioat.c | 4 ++-- lib/util/io_channel.c | 9 ++++++-- test/lib/util/io_channel/io_channel_ut.c | 28 ++++++++++++++++-------- 7 files changed, 43 insertions(+), 23 deletions(-) diff --git a/include/spdk/io_channel.h b/include/spdk/io_channel.h index 59735ec02..4f510148a 100644 --- a/include/spdk/io_channel.h +++ b/include/spdk/io_channel.h @@ -46,7 +46,8 @@ struct spdk_io_channel; -typedef int (*io_channel_create_cb_t)(void *io_device, uint32_t priority, void *ctx_buf); +typedef int (*io_channel_create_cb_t)(void *io_device, uint32_t priority, void *ctx_buf, + void *unique_ctx); typedef void (*io_channel_destroy_cb_t)(void *io_device, void *ctx_buf); /** @@ -99,8 +100,12 @@ void spdk_io_device_unregister(void *io_device); * * The unique parameter allows callers to specify that an existing channel should not * be used to satisfy this request, even if the io_device and priority fields match. + * + * The unique_ctx parameter allows callers to pass channel-specific context to the create_cb + * handler for unique channels. This value must be NULL for shared channels. */ -struct spdk_io_channel *spdk_get_io_channel(void *io_device, uint32_t priority, bool unique); +struct spdk_io_channel *spdk_get_io_channel(void *io_device, uint32_t priority, bool unique, + void *unique_ctx); /** * \brief Releases a reference to an I/O channel. diff --git a/lib/bdev/aio/blockdev_aio.c b/lib/bdev/aio/blockdev_aio.c index b9a197d1c..e259f9f3b 100644 --- a/lib/bdev/aio/blockdev_aio.c +++ b/lib/bdev/aio/blockdev_aio.c @@ -310,7 +310,7 @@ blockdev_aio_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type io } static int -blockdev_aio_create_cb(void *io_device, uint32_t priority, void *ctx_buf) +blockdev_aio_create_cb(void *io_device, uint32_t priority, void *ctx_buf, void *unique_ctx) { struct blockdev_aio_io_channel *ch = ctx_buf; @@ -336,7 +336,7 @@ blockdev_aio_destroy_cb(void *io_device, void *ctx_buf) static struct spdk_io_channel * blockdev_aio_get_io_channel(struct spdk_bdev *bdev, uint32_t priority) { - return spdk_get_io_channel(bdev, priority, false); + return spdk_get_io_channel(bdev, priority, false, NULL); } static const struct spdk_bdev_fn_table aio_fn_table = { diff --git a/lib/bdev/nvme/blockdev_nvme.c b/lib/bdev/nvme/blockdev_nvme.c index d9883ed6c..daf1e047d 100644 --- a/lib/bdev/nvme/blockdev_nvme.c +++ b/lib/bdev/nvme/blockdev_nvme.c @@ -306,7 +306,7 @@ blockdev_nvme_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type i } static int -blockdev_nvme_create_cb(void *io_device, uint32_t priority, void *ctx_buf) +blockdev_nvme_create_cb(void *io_device, uint32_t priority, void *ctx_buf, void *unique_ctx) { struct spdk_nvme_ctrlr *ctrlr = io_device; struct nvme_io_channel *ch = ctx_buf; @@ -336,7 +336,7 @@ blockdev_nvme_get_io_channel(struct spdk_bdev *bdev, uint32_t priority) { struct nvme_blockdev *nvme_bdev = (struct nvme_blockdev *)bdev; - return spdk_get_io_channel(nvme_bdev->ctrlr, priority, false); + return spdk_get_io_channel(nvme_bdev->ctrlr, priority, false, NULL); } static const struct spdk_bdev_fn_table nvmelib_fn_table = { diff --git a/lib/copy/copy_engine.c b/lib/copy/copy_engine.c index d89324662..5308839e8 100644 --- a/lib/copy/copy_engine.c +++ b/lib/copy/copy_engine.c @@ -139,7 +139,7 @@ static struct spdk_copy_engine memcpy_copy_engine = { }; static int -memcpy_create_cb(void *io_device, uint32_t priority, void *ctx_buf) +memcpy_create_cb(void *io_device, uint32_t priority, void *ctx_buf, void *unique_ctx) { return 0; } @@ -151,7 +151,7 @@ memcpy_destroy_cb(void *io_device, void *ctx_buf) static struct spdk_io_channel *mem_get_io_channel(uint32_t priority) { - return spdk_get_io_channel(&memcpy_copy_engine, priority, false); + return spdk_get_io_channel(&memcpy_copy_engine, priority, false, NULL); } static int @@ -179,7 +179,7 @@ void spdk_copy_module_list_add(struct spdk_copy_module_if *copy_module) } static int -copy_create_cb(void *io_device, uint32_t priority, void *ctx_buf) +copy_create_cb(void *io_device, uint32_t priority, void *ctx_buf, void *unique_ctx) { struct copy_io_channel *copy_ch = ctx_buf; @@ -208,7 +208,7 @@ copy_destroy_cb(void *io_device, void *ctx_buf) struct spdk_io_channel * spdk_copy_engine_get_io_channel(uint32_t priority) { - return spdk_get_io_channel(&spdk_copy_module_list, priority, false); + return spdk_get_io_channel(&spdk_copy_module_list, priority, false, NULL); } static int diff --git a/lib/copy/ioat/copy_engine_ioat.c b/lib/copy/ioat/copy_engine_ioat.c index 794400161..5acc66802 100644 --- a/lib/copy/ioat/copy_engine_ioat.c +++ b/lib/copy/ioat/copy_engine_ioat.c @@ -207,7 +207,7 @@ static struct spdk_copy_engine ioat_copy_engine = { }; static int -ioat_create_cb(void *io_device, uint32_t priority, void *ctx_buf) +ioat_create_cb(void *io_device, uint32_t priority, void *ctx_buf, void *unique_ctx) { struct ioat_io_channel *ch = ctx_buf; struct ioat_device *ioat_dev; @@ -236,7 +236,7 @@ ioat_destroy_cb(void *io_device, void *ctx_buf) static struct spdk_io_channel * ioat_get_io_channel(uint32_t priority) { - return spdk_get_io_channel(&ioat_copy_engine, priority, false); + return spdk_get_io_channel(&ioat_copy_engine, priority, false, NULL); } struct ioat_probe_ctx { diff --git a/lib/util/io_channel.c b/lib/util/io_channel.c index ce2ab16da..a24a95a1e 100644 --- a/lib/util/io_channel.c +++ b/lib/util/io_channel.c @@ -130,7 +130,7 @@ spdk_io_device_unregister(void *io_device) } struct spdk_io_channel * -spdk_get_io_channel(void *io_device, uint32_t priority, bool unique) +spdk_get_io_channel(void *io_device, uint32_t priority, bool unique, void *unique_ctx) { struct spdk_io_channel *ch; struct io_device *dev; @@ -141,6 +141,11 @@ spdk_get_io_channel(void *io_device, uint32_t priority, bool unique) return NULL; } + if (unique == false && unique_ctx != NULL) { + SPDK_ERRLOG("non-NULL unique_ctx passed for shared channel\n"); + return NULL; + } + pthread_mutex_lock(&g_devlist_mutex); TAILQ_FOREACH(dev, &g_io_devices, tailq) { if (dev->io_device_ctx == io_device) { @@ -172,7 +177,7 @@ spdk_get_io_channel(void *io_device, uint32_t priority, bool unique) SPDK_ERRLOG("could not calloc spdk_io_channel\n"); return NULL; } - rc = dev->create_cb(io_device, priority, (uint8_t *)ch + sizeof(*ch)); + rc = dev->create_cb(io_device, priority, (uint8_t *)ch + sizeof(*ch), unique_ctx); if (rc == -1) { free(ch); return NULL; diff --git a/test/lib/util/io_channel/io_channel_ut.c b/test/lib/util/io_channel/io_channel_ut.c index 0ddf56099..106e39d6b 100644 --- a/test/lib/util/io_channel/io_channel_ut.c +++ b/test/lib/util/io_channel/io_channel_ut.c @@ -57,7 +57,7 @@ static int g_create_cb_calls = 0; static int g_destroy_cb_calls = 0; static int -create_cb_1(void *io_device, uint32_t priority, void *ctx_buf) +create_cb_1(void *io_device, uint32_t priority, void *ctx_buf, void *unique_ctx) { CU_ASSERT(io_device == &device1); CU_ASSERT(priority == SPDK_IO_PRIORITY_DEFAULT); @@ -75,12 +75,15 @@ destroy_cb_1(void *io_device, void *ctx_buf) } static int -create_cb_2(void *io_device, uint32_t priority, void *ctx_buf) +create_cb_2(void *io_device, uint32_t priority, void *ctx_buf, void *unique_ctx) { CU_ASSERT(io_device == &device2); CU_ASSERT(priority == SPDK_IO_PRIORITY_DEFAULT); *(uint64_t *)ctx_buf = ctx2; g_create_cb_calls++; + if (unique_ctx != NULL) { + *(int *)unique_ctx = ~(*(int *)unique_ctx); + } return 0; } @@ -93,7 +96,7 @@ destroy_cb_2(void *io_device, void *ctx_buf) } static int -create_cb_null(void *io_device, uint32_t priority, void *ctx_buf) +create_cb_null(void *io_device, uint32_t priority, void *ctx_buf, void *unique_ctx) { return -1; } @@ -102,6 +105,7 @@ static void channel(void) { struct spdk_io_channel *ch1, *ch2, *ch3; + int tmp; void *ctx; spdk_allocate_thread(); @@ -110,12 +114,12 @@ channel(void) spdk_io_device_register(&device3, create_cb_null, NULL, 0); g_create_cb_calls = 0; - ch1 = spdk_get_io_channel(&device1, SPDK_IO_PRIORITY_DEFAULT, false); + ch1 = spdk_get_io_channel(&device1, SPDK_IO_PRIORITY_DEFAULT, false, NULL); CU_ASSERT(g_create_cb_calls == 1); SPDK_CU_ASSERT_FATAL(ch1 != NULL); g_create_cb_calls = 0; - ch2 = spdk_get_io_channel(&device1, SPDK_IO_PRIORITY_DEFAULT, false); + ch2 = spdk_get_io_channel(&device1, SPDK_IO_PRIORITY_DEFAULT, false, NULL); CU_ASSERT(g_create_cb_calls == 0); CU_ASSERT(ch1 == ch2); SPDK_CU_ASSERT_FATAL(ch2 != NULL); @@ -125,7 +129,7 @@ channel(void) CU_ASSERT(g_destroy_cb_calls == 0); g_create_cb_calls = 0; - ch2 = spdk_get_io_channel(&device2, SPDK_IO_PRIORITY_DEFAULT, false); + ch2 = spdk_get_io_channel(&device2, SPDK_IO_PRIORITY_DEFAULT, false, NULL); CU_ASSERT(g_create_cb_calls == 1); CU_ASSERT(ch1 != ch2); SPDK_CU_ASSERT_FATAL(ch2 != NULL); @@ -138,10 +142,12 @@ channel(void) * and reuse ch2. */ g_create_cb_calls = 0; - ch3 = spdk_get_io_channel(&device2, SPDK_IO_PRIORITY_DEFAULT, true); + tmp = 0x5a5a; + ch3 = spdk_get_io_channel(&device2, SPDK_IO_PRIORITY_DEFAULT, true, &tmp); CU_ASSERT(g_create_cb_calls == 1); CU_ASSERT(ch2 != ch3); CU_ASSERT(ch3 != NULL); + CU_ASSERT(tmp == ~0x5a5a); g_destroy_cb_calls = 0; spdk_put_io_channel(ch1); @@ -155,11 +161,15 @@ channel(void) spdk_put_io_channel(ch3); CU_ASSERT(g_destroy_cb_calls == 1); - ch1 = spdk_get_io_channel(&device3, SPDK_IO_PRIORITY_DEFAULT, false); + ch1 = spdk_get_io_channel(&device3, SPDK_IO_PRIORITY_DEFAULT, false, NULL); CU_ASSERT(ch1 == NULL); /* Confirm failure if user specifies an invalid I/O priority. */ - ch1 = spdk_get_io_channel(&device1, SPDK_IO_PRIORITY_DEFAULT + 1, false); + ch1 = spdk_get_io_channel(&device1, SPDK_IO_PRIORITY_DEFAULT + 1, false, NULL); + CU_ASSERT(ch1 == NULL); + + /* Confirm failure if user specifies non-NULL unique_ctx for a shared channel. */ + ch1 = spdk_get_io_channel(&device1, SPDK_IO_PRIORITY_DEFAULT, false, &tmp); CU_ASSERT(ch1 == NULL); spdk_io_device_unregister(&device1);