From 746a54bef8cdcff5245563c07cefb16eded20da7 Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Fri, 16 Sep 2016 12:53:32 -0700 Subject: [PATCH] bdev: create new get_channel/put_channel function pointers Also implement these functions for all of the bdev drivers in the tree. Signed-off-by: Jim Harris Change-Id: Idea97743d601150044b1fe2d9d76e922d46d3ee1 --- include/spdk/bdev.h | 5 ++- lib/bdev/aio/blockdev_aio.c | 34 ++++++++++++++++++++ lib/bdev/aio/blockdev_aio.h | 1 + lib/bdev/bdev.c | 6 ++++ lib/bdev/malloc/blockdev_malloc.c | 8 +++++ lib/bdev/nvme/blockdev_nvme.c | 53 ++++++++++++++++++++++++++++++- 6 files changed, 105 insertions(+), 2 deletions(-) diff --git a/include/spdk/bdev.h b/include/spdk/bdev.h index f1c029e94..4a8e5dd69 100644 --- a/include/spdk/bdev.h +++ b/include/spdk/bdev.h @@ -146,6 +146,9 @@ struct spdk_bdev_fn_table { /** Check if the block device supports a specific I/O type. */ bool (*io_type_supported)(struct spdk_bdev *bdev, enum spdk_bdev_io_type); + + /** Get an I/O channel for the specific bdev for the calling thread. */ + struct spdk_io_channel *(*get_io_channel)(struct spdk_bdev *bdev, uint32_t priority); }; /** Blockdev I/O completion status */ @@ -308,5 +311,5 @@ void spdk_bdev_do_work(void *ctx); int spdk_bdev_free_io(struct spdk_bdev_io *bdev_io); int spdk_bdev_reset(struct spdk_bdev *bdev, enum spdk_bdev_reset_type, spdk_bdev_io_completion_cb cb, void *cb_arg); - +struct spdk_io_channel *spdk_bdev_get_io_channel(struct spdk_bdev *bdev, uint32_t priority); #endif /* SPDK_BDEV_H_ */ diff --git a/lib/bdev/aio/blockdev_aio.c b/lib/bdev/aio/blockdev_aio.c index a5165606c..4a596a731 100644 --- a/lib/bdev/aio/blockdev_aio.c +++ b/lib/bdev/aio/blockdev_aio.c @@ -45,6 +45,7 @@ #include "spdk/conf.h" #include "spdk/fd.h" #include "spdk/log.h" +#include "spdk/io_channel.h" static int g_blockdev_count = 0; @@ -314,11 +315,42 @@ 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) +{ + struct blockdev_aio_io_channel *ch = ctx_buf; + + if (blockdev_aio_initialize_io_channel(ch) != 0) { + return -1; + } + + spdk_poller_register(&ch->poller, blockdev_aio_poll, ch, + spdk_app_get_current_core(), NULL, 0); + return 0; +} + +static void +blockdev_aio_destroy_cb(void *io_device, void *ctx_buf) +{ + struct blockdev_aio_io_channel *io_channel = ctx_buf; + + io_destroy(io_channel->io_ctx); + free(io_channel->events); + spdk_poller_unregister(&io_channel->poller, NULL); +} + +static struct spdk_io_channel * +blockdev_aio_get_io_channel(struct spdk_bdev *bdev, uint32_t priority) +{ + return spdk_get_io_channel(bdev, priority); +} + static const struct spdk_bdev_fn_table aio_fn_table = { .destruct = blockdev_aio_destruct, .check_io = blockdev_aio_check_io, .submit_request = blockdev_aio_submit_request, .io_type_supported = blockdev_aio_io_type_supported, + .get_io_channel = blockdev_aio_get_io_channel, }; static void aio_free_disk(struct file_disk *fdisk) @@ -367,6 +399,8 @@ create_aio_disk(char *fname) g_blockdev_count++; + spdk_io_device_register(&fdisk->disk, blockdev_aio_create_cb, blockdev_aio_destroy_cb, + sizeof(struct blockdev_aio_io_channel)); spdk_bdev_register(&fdisk->disk); return fdisk; diff --git a/lib/bdev/aio/blockdev_aio.h b/lib/bdev/aio/blockdev_aio.h index 851fc22f8..29638d476 100644 --- a/lib/bdev/aio/blockdev_aio.h +++ b/lib/bdev/aio/blockdev_aio.h @@ -52,6 +52,7 @@ struct blockdev_aio_io_channel { io_context_t io_ctx; long queue_depth; struct io_event *events; + struct spdk_poller *poller; }; struct file_disk { diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index f63279b23..e714f7170 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -535,6 +535,12 @@ spdk_bdev_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type io_ty return bdev->fn_table->io_type_supported(bdev, io_type); } +struct spdk_io_channel * +spdk_bdev_get_io_channel(struct spdk_bdev *bdev, uint32_t priority) +{ + return bdev->fn_table->get_io_channel(bdev, priority); +} + struct spdk_bdev_io * spdk_bdev_read(struct spdk_bdev *bdev, void *buf, uint64_t offset, uint64_t nbytes, diff --git a/lib/bdev/malloc/blockdev_malloc.c b/lib/bdev/malloc/blockdev_malloc.c index 5d6081a15..270d2cca0 100644 --- a/lib/bdev/malloc/blockdev_malloc.c +++ b/lib/bdev/malloc/blockdev_malloc.c @@ -44,6 +44,7 @@ #include "spdk/endian.h" #include "spdk/log.h" #include "spdk/copy_engine.h" +#include "spdk/io_channel.h" #include "bdev_module.h" @@ -266,11 +267,18 @@ blockdev_malloc_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type } } +static struct spdk_io_channel * +blockdev_malloc_get_io_channel(struct spdk_bdev *bdev, uint32_t priority) +{ + return spdk_copy_engine_get_io_channel(priority); +} + static const struct spdk_bdev_fn_table malloc_fn_table = { .destruct = blockdev_malloc_destruct, .check_io = blockdev_malloc_check_io, .submit_request = blockdev_malloc_submit_request, .io_type_supported = blockdev_malloc_io_type_supported, + .get_io_channel = blockdev_malloc_get_io_channel, }; struct malloc_disk *create_malloc_disk(uint64_t num_blocks, uint32_t block_size) diff --git a/lib/bdev/nvme/blockdev_nvme.c b/lib/bdev/nvme/blockdev_nvme.c index 3eb7615e8..2ed097bc9 100644 --- a/lib/bdev/nvme/blockdev_nvme.c +++ b/lib/bdev/nvme/blockdev_nvme.c @@ -52,6 +52,7 @@ #include "spdk/log.h" #include "spdk/bdev.h" #include "spdk/nvme.h" +#include "spdk/io_channel.h" #include "bdev_module.h" @@ -84,6 +85,11 @@ struct nvme_blockdev { uint64_t blocklen; }; +struct nvme_io_channel { + struct spdk_nvme_qpair *qpair; + struct spdk_poller *poller; +}; + #define NVME_DEFAULT_MAX_UNMAP_BDESC_COUNT 1 struct nvme_blockio { struct spdk_nvme_dsm_range dsm_range[NVME_DEFAULT_MAX_UNMAP_BDESC_COUNT]; @@ -168,12 +174,20 @@ blockdev_nvme_writev(struct nvme_blockdev *nbdev, struct nvme_blockio *bio, return iov->iov_len; } +static void +blockdev_nvme_poll(void *arg) +{ + struct spdk_nvme_qpair *qpair = arg; + + spdk_nvme_qpair_process_completions(qpair, 0); +} + static int blockdev_nvme_check_io(struct spdk_bdev *bdev) { struct nvme_blockdev *nbdev = (struct nvme_blockdev *)bdev; - spdk_nvme_qpair_process_completions(nbdev->qpair, 0); + blockdev_nvme_poll(nbdev->qpair); return 0; } @@ -295,11 +309,46 @@ 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) +{ + struct spdk_nvme_ctrlr *ctrlr = io_device; + struct nvme_io_channel *ch = ctx_buf; + + ch->qpair = spdk_nvme_ctrlr_alloc_io_qpair(ctrlr, 0); + + if (ch->qpair == NULL) { + return -1; + } + + spdk_poller_register(&ch->poller, blockdev_nvme_poll, ch->qpair, + spdk_app_get_current_core(), NULL, 0); + return 0; +} + +static void +blockdev_nvme_destroy_cb(void *io_device, void *ctx_buf) +{ + struct nvme_io_channel *ch = ctx_buf; + + spdk_nvme_ctrlr_free_io_qpair(ch->qpair); + spdk_poller_unregister(&ch->poller, NULL); +} + +static struct spdk_io_channel * +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); +} + static const struct spdk_bdev_fn_table nvmelib_fn_table = { .destruct = blockdev_nvme_destruct, .check_io = blockdev_nvme_check_io, .submit_request = blockdev_nvme_submit_request, .io_type_supported = blockdev_nvme_io_type_supported, + .get_io_channel = blockdev_nvme_get_io_channel, }; struct nvme_probe_ctx { @@ -390,6 +439,8 @@ attach_cb(void *cb_ctx, struct spdk_pci_device *pci_dev, struct spdk_nvme_ctrlr dev->id = nvme_controller_index++; nvme_ctrlr_initialize_blockdevs(dev->ctrlr, nvme_luns_per_ns, dev->id); + spdk_io_device_register(ctrlr, blockdev_nvme_create_cb, blockdev_nvme_destroy_cb, + sizeof(struct nvme_io_channel)); TAILQ_INSERT_TAIL(&g_nvme_devices, dev, tailq); if (ctx->controllers_remaining > 0) {