From 06ef766bc03ac0a616e2c432de677eefcdcbcf6c Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Tue, 20 Sep 2016 12:46:28 -0700 Subject: [PATCH] scsi: add spdk_io_channel support Signed-off-by: Jim Harris Change-Id: I189ea68c8550bbaeab79be36cb3c4faba7cd2f69 --- include/spdk/scsi.h | 11 +++++++++++ lib/scsi/dev.c | 31 +++++++++++++++++++++++++++++++ lib/scsi/lun.c | 27 +++++++++++++++++++++++++++ lib/scsi/scsi_internal.h | 2 ++ test/lib/scsi/dev/dev_ut.c | 11 +++++++++++ test/lib/scsi/lun/lun_ut.c | 12 +++++++++++- 6 files changed, 93 insertions(+), 1 deletion(-) diff --git a/include/spdk/scsi.h b/include/spdk/scsi.h index 3f04ad784..796dc7830 100644 --- a/include/spdk/scsi.h +++ b/include/spdk/scsi.h @@ -41,6 +41,7 @@ #include #include +#include #include #include "spdk/queue.h" @@ -193,6 +194,14 @@ struct spdk_scsi_lun { /** The blockdev associated with this LUN. */ struct spdk_bdev *bdev; + /** I/O channel for the blockdev associated with this LUN. */ + struct spdk_io_channel *io_channel; + + /** Thread ID for the thread that allocated the I/O channel for this + * LUN. All I/O to this LUN must be performed from this thread. + */ + pthread_t thread_id; + /** Name for this LUN. */ char name[SPDK_SCSI_LUN_MAX_NAME_LENGTH]; @@ -206,6 +215,8 @@ void spdk_scsi_dev_queue_task(struct spdk_scsi_dev *dev, struct spdk_scsi_task * int spdk_scsi_dev_add_port(struct spdk_scsi_dev *dev, uint64_t id, const char *name); struct spdk_scsi_port *spdk_scsi_dev_find_port_by_id(struct spdk_scsi_dev *dev, uint64_t id); void spdk_scsi_dev_print(struct spdk_scsi_dev *dev); +int spdk_scsi_dev_allocate_io_channels(struct spdk_scsi_dev *dev); +void spdk_scsi_dev_free_io_channels(struct spdk_scsi_dev *dev); /** diff --git a/lib/scsi/dev.c b/lib/scsi/dev.c index c5378bbf0..8d76d9cc0 100644 --- a/lib/scsi/dev.c +++ b/lib/scsi/dev.c @@ -256,3 +256,34 @@ spdk_scsi_dev_print(struct spdk_scsi_dev *dev) } } +void +spdk_scsi_dev_free_io_channels(struct spdk_scsi_dev *dev) +{ + int i; + + for (i = 0; i < SPDK_SCSI_DEV_MAX_LUN; i++) { + if (dev->lun[i] == NULL) { + continue; + } + spdk_scsi_lun_free_io_channel(dev->lun[i]); + } +} + +int +spdk_scsi_dev_allocate_io_channels(struct spdk_scsi_dev *dev) +{ + int i, rc; + + for (i = 0; i < SPDK_SCSI_DEV_MAX_LUN; i++) { + if (dev->lun[i] == NULL) { + continue; + } + rc = spdk_scsi_lun_allocate_io_channel(dev->lun[i]); + if (rc < 0) { + spdk_scsi_dev_free_io_channels(dev); + return -1; + } + } + + return 0; +} diff --git a/lib/scsi/lun.c b/lib/scsi/lun.c index 31a7c208c..737fa63ed 100644 --- a/lib/scsi/lun.c +++ b/lib/scsi/lun.c @@ -34,6 +34,7 @@ #include "scsi_internal.h" #include "spdk/endian.h" +#include "spdk/io_channel.h" void spdk_scsi_lun_complete_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task) @@ -391,3 +392,29 @@ spdk_scsi_lun_delete(const char *lun_name) spdk_scsi_lun_destruct(lun); pthread_mutex_unlock(&g_spdk_scsi.mutex); } + +int spdk_scsi_lun_allocate_io_channel(struct spdk_scsi_lun *lun) +{ + if (lun->io_channel != NULL) { + if (pthread_self() == lun->thread_id) { + return 0; + } + SPDK_ERRLOG("io_channel already allocated for lun %s\n", lun->name); + return -1; + } + + lun->io_channel = spdk_bdev_get_io_channel(lun->bdev, SPDK_IO_PRIORITY_DEFAULT); + if (lun->io_channel == NULL) { + return -1; + } + lun->thread_id = pthread_self(); + return 0; +} + +void spdk_scsi_lun_free_io_channel(struct spdk_scsi_lun *lun) +{ + if (lun->io_channel != NULL) { + spdk_put_io_channel(lun->io_channel); + lun->io_channel = NULL; + } +} diff --git a/lib/scsi/scsi_internal.h b/lib/scsi/scsi_internal.h index 6f5115100..1ce04d44c 100644 --- a/lib/scsi/scsi_internal.h +++ b/lib/scsi/scsi_internal.h @@ -85,6 +85,8 @@ int spdk_scsi_lun_claim(struct spdk_scsi_lun *lun); int spdk_scsi_lun_unclaim(struct spdk_scsi_lun *lun); int spdk_scsi_lun_deletable(const char *name); void spdk_scsi_lun_delete(const char *lun_name); +int spdk_scsi_lun_allocate_io_channel(struct spdk_scsi_lun *lun); +void spdk_scsi_lun_free_io_channel(struct spdk_scsi_lun *lun); int spdk_scsi_lun_db_add(struct spdk_scsi_lun *lun); int spdk_scsi_lun_db_delete(struct spdk_scsi_lun *lun); diff --git a/test/lib/scsi/dev/dev_ut.c b/test/lib/scsi/dev/dev_ut.c index ad5cca8df..fe8c086bb 100644 --- a/test/lib/scsi/dev/dev_ut.c +++ b/test/lib/scsi/dev/dev_ut.c @@ -117,6 +117,17 @@ spdk_scsi_lun_execute_tasks(struct spdk_scsi_lun *lun) { } +int +spdk_scsi_lun_allocate_io_channel(struct spdk_scsi_lun *lun) +{ + return 0; +} + +void +spdk_scsi_lun_free_io_channel(struct spdk_scsi_lun *lun) +{ +} + static void dev_destruct_null_dev(void) diff --git a/test/lib/scsi/lun/lun_ut.c b/test/lib/scsi/lun/lun_ut.c index 551dc4ac8..8b8030263 100644 --- a/test/lib/scsi/lun/lun_ut.c +++ b/test/lib/scsi/lun/lun_ut.c @@ -140,7 +140,17 @@ spdk_bdev_scsi_execute(struct spdk_bdev *bdev, struct spdk_scsi_task *task) void spdk_bdev_unregister(struct spdk_bdev *bdev) { - return; +} + +struct spdk_io_channel * +spdk_bdev_get_io_channel(struct spdk_bdev *bdev, uint32_t priority) +{ + return NULL; +} + +void +spdk_put_io_channel(struct spdk_io_channel *ch) +{ } void spdk_event_call(spdk_event_t event)