util: add context parameter for unique I/O channels
Signed-off-by: Jim Harris <james.r.harris@intel.com> Change-Id: I296992b2e03b9b516cfd26726405e49616ad08a5
This commit is contained in:
parent
c1e3a87bf7
commit
32aa4fa0a3
@ -46,7 +46,8 @@
|
|||||||
|
|
||||||
struct spdk_io_channel;
|
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);
|
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
|
* 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.
|
* 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.
|
* \brief Releases a reference to an I/O channel.
|
||||||
|
@ -310,7 +310,7 @@ blockdev_aio_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type io
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
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 *
|
static struct spdk_io_channel *
|
||||||
blockdev_aio_get_io_channel(struct spdk_bdev *bdev, uint32_t priority)
|
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 = {
|
static const struct spdk_bdev_fn_table aio_fn_table = {
|
||||||
|
@ -306,7 +306,7 @@ blockdev_nvme_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type i
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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 spdk_nvme_ctrlr *ctrlr = io_device;
|
||||||
struct nvme_io_channel *ch = ctx_buf;
|
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;
|
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 = {
|
static const struct spdk_bdev_fn_table nvmelib_fn_table = {
|
||||||
|
@ -139,7 +139,7 @@ static struct spdk_copy_engine memcpy_copy_engine = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int
|
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;
|
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)
|
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
|
static int
|
||||||
@ -179,7 +179,7 @@ void spdk_copy_module_list_add(struct spdk_copy_module_if *copy_module)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
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 *
|
struct spdk_io_channel *
|
||||||
spdk_copy_engine_get_io_channel(uint32_t priority)
|
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
|
static int
|
||||||
|
@ -207,7 +207,7 @@ static struct spdk_copy_engine ioat_copy_engine = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int
|
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_io_channel *ch = ctx_buf;
|
||||||
struct ioat_device *ioat_dev;
|
struct ioat_device *ioat_dev;
|
||||||
@ -236,7 +236,7 @@ ioat_destroy_cb(void *io_device, void *ctx_buf)
|
|||||||
static struct spdk_io_channel *
|
static struct spdk_io_channel *
|
||||||
ioat_get_io_channel(uint32_t priority)
|
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 {
|
struct ioat_probe_ctx {
|
||||||
|
@ -130,7 +130,7 @@ spdk_io_device_unregister(void *io_device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct spdk_io_channel *
|
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 spdk_io_channel *ch;
|
||||||
struct io_device *dev;
|
struct io_device *dev;
|
||||||
@ -141,6 +141,11 @@ spdk_get_io_channel(void *io_device, uint32_t priority, bool unique)
|
|||||||
return NULL;
|
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);
|
pthread_mutex_lock(&g_devlist_mutex);
|
||||||
TAILQ_FOREACH(dev, &g_io_devices, tailq) {
|
TAILQ_FOREACH(dev, &g_io_devices, tailq) {
|
||||||
if (dev->io_device_ctx == io_device) {
|
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");
|
SPDK_ERRLOG("could not calloc spdk_io_channel\n");
|
||||||
return NULL;
|
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) {
|
if (rc == -1) {
|
||||||
free(ch);
|
free(ch);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -57,7 +57,7 @@ static int g_create_cb_calls = 0;
|
|||||||
static int g_destroy_cb_calls = 0;
|
static int g_destroy_cb_calls = 0;
|
||||||
|
|
||||||
static int
|
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(io_device == &device1);
|
||||||
CU_ASSERT(priority == SPDK_IO_PRIORITY_DEFAULT);
|
CU_ASSERT(priority == SPDK_IO_PRIORITY_DEFAULT);
|
||||||
@ -75,12 +75,15 @@ destroy_cb_1(void *io_device, void *ctx_buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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(io_device == &device2);
|
||||||
CU_ASSERT(priority == SPDK_IO_PRIORITY_DEFAULT);
|
CU_ASSERT(priority == SPDK_IO_PRIORITY_DEFAULT);
|
||||||
*(uint64_t *)ctx_buf = ctx2;
|
*(uint64_t *)ctx_buf = ctx2;
|
||||||
g_create_cb_calls++;
|
g_create_cb_calls++;
|
||||||
|
if (unique_ctx != NULL) {
|
||||||
|
*(int *)unique_ctx = ~(*(int *)unique_ctx);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +96,7 @@ destroy_cb_2(void *io_device, void *ctx_buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -102,6 +105,7 @@ static void
|
|||||||
channel(void)
|
channel(void)
|
||||||
{
|
{
|
||||||
struct spdk_io_channel *ch1, *ch2, *ch3;
|
struct spdk_io_channel *ch1, *ch2, *ch3;
|
||||||
|
int tmp;
|
||||||
void *ctx;
|
void *ctx;
|
||||||
|
|
||||||
spdk_allocate_thread();
|
spdk_allocate_thread();
|
||||||
@ -110,12 +114,12 @@ channel(void)
|
|||||||
spdk_io_device_register(&device3, create_cb_null, NULL, 0);
|
spdk_io_device_register(&device3, create_cb_null, NULL, 0);
|
||||||
|
|
||||||
g_create_cb_calls = 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);
|
CU_ASSERT(g_create_cb_calls == 1);
|
||||||
SPDK_CU_ASSERT_FATAL(ch1 != NULL);
|
SPDK_CU_ASSERT_FATAL(ch1 != NULL);
|
||||||
|
|
||||||
g_create_cb_calls = 0;
|
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(g_create_cb_calls == 0);
|
||||||
CU_ASSERT(ch1 == ch2);
|
CU_ASSERT(ch1 == ch2);
|
||||||
SPDK_CU_ASSERT_FATAL(ch2 != NULL);
|
SPDK_CU_ASSERT_FATAL(ch2 != NULL);
|
||||||
@ -125,7 +129,7 @@ channel(void)
|
|||||||
CU_ASSERT(g_destroy_cb_calls == 0);
|
CU_ASSERT(g_destroy_cb_calls == 0);
|
||||||
|
|
||||||
g_create_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(g_create_cb_calls == 1);
|
||||||
CU_ASSERT(ch1 != ch2);
|
CU_ASSERT(ch1 != ch2);
|
||||||
SPDK_CU_ASSERT_FATAL(ch2 != NULL);
|
SPDK_CU_ASSERT_FATAL(ch2 != NULL);
|
||||||
@ -138,10 +142,12 @@ channel(void)
|
|||||||
* and reuse ch2.
|
* and reuse ch2.
|
||||||
*/
|
*/
|
||||||
g_create_cb_calls = 0;
|
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(g_create_cb_calls == 1);
|
||||||
CU_ASSERT(ch2 != ch3);
|
CU_ASSERT(ch2 != ch3);
|
||||||
CU_ASSERT(ch3 != NULL);
|
CU_ASSERT(ch3 != NULL);
|
||||||
|
CU_ASSERT(tmp == ~0x5a5a);
|
||||||
|
|
||||||
g_destroy_cb_calls = 0;
|
g_destroy_cb_calls = 0;
|
||||||
spdk_put_io_channel(ch1);
|
spdk_put_io_channel(ch1);
|
||||||
@ -155,11 +161,15 @@ channel(void)
|
|||||||
spdk_put_io_channel(ch3);
|
spdk_put_io_channel(ch3);
|
||||||
CU_ASSERT(g_destroy_cb_calls == 1);
|
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);
|
CU_ASSERT(ch1 == NULL);
|
||||||
|
|
||||||
/* Confirm failure if user specifies an invalid I/O priority. */
|
/* 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);
|
CU_ASSERT(ch1 == NULL);
|
||||||
|
|
||||||
spdk_io_device_unregister(&device1);
|
spdk_io_device_unregister(&device1);
|
||||||
|
Loading…
Reference in New Issue
Block a user