From ca1b5c418db1783666a800e166532e4fda0706f2 Mon Sep 17 00:00:00 2001 From: Vitaliy Mysak Date: Fri, 1 Mar 2019 21:47:31 +0000 Subject: [PATCH] ocf: switch to dynamic queues Use new queue API to manage OCF queues dynamically This change allows for dynamic creation and deletion of queues on get_ and put_ io channel. Qeueues no longer depend on number of cores in SPDK. Queue-to-pollers mapping list is removed as well as locks "q_ocf_lock" and "vbdev->_lock" as they became redundant Change-Id: I5069e1f8535f505816184a333db876afb925ac44 Signed-off-by: Vitaliy Mysak Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/446841 Tested-by: SPDK CI Jenkins Reviewed-by: Ben Walker Reviewed-by: Tomasz Zawadzki Reviewed-by: Darek Stojaczyk --- lib/bdev/ocf/ctx.c | 28 ------------- lib/bdev/ocf/vbdev_ocf.c | 87 ++++++++++++---------------------------- lib/bdev/ocf/vbdev_ocf.h | 7 ---- lib/bdev/ocf/volume.c | 23 +++++------ ocf | 2 +- 5 files changed, 35 insertions(+), 112 deletions(-) diff --git a/lib/bdev/ocf/ctx.c b/lib/bdev/ocf/ctx.c index 7e23cfc30..96bbc0ad8 100644 --- a/lib/bdev/ocf/ctx.c +++ b/lib/bdev/ocf/ctx.c @@ -287,28 +287,6 @@ vbdev_ocf_ctx_data_secure_erase(ctx_data_t *ctx_data) } } -/* OCF queue initialization procedure - * Called during ocf_cache_start */ -static int -vbdev_ocf_ctx_queue_init(ocf_queue_t q) -{ - return 0; -} - -/* Called during ocf_submit_io, ocf_purge* - * and any other requests that need to submit io */ -static void -vbdev_ocf_ctx_queue_kick(ocf_queue_t q) -{ -} - -/* OCF queue deinitialization - * Called at ocf_cache_stop */ -static void -vbdev_ocf_ctx_queue_stop(ocf_queue_t q) -{ -} - static int vbdev_ocf_ctx_cleaner_init(ocf_cleaner_t c) { @@ -374,12 +352,6 @@ static const struct ocf_ctx_config vbdev_ocf_ctx_cfg = { .secure_erase = vbdev_ocf_ctx_data_secure_erase, }, - .queue = { - .init = vbdev_ocf_ctx_queue_init, - .kick = vbdev_ocf_ctx_queue_kick, - .stop = vbdev_ocf_ctx_queue_stop, - }, - .metadata_updater = { .init = vbdev_ocf_volume_updater_init, .stop = vbdev_ocf_volume_updater_stop, diff --git a/lib/bdev/ocf/vbdev_ocf.c b/lib/bdev/ocf/vbdev_ocf.c index 694172f63..07563a0a4 100644 --- a/lib/bdev/ocf/vbdev_ocf.c +++ b/lib/bdev/ocf/vbdev_ocf.c @@ -50,10 +50,6 @@ static struct spdk_bdev_module ocf_if; -/* Set number of OCF queues to maximum numbers of cores - * that SPDK supports, so we never run out of them */ -static int g_queues_count = SPDK_CPUSET_SIZE; - static TAILQ_HEAD(, vbdev_ocf) g_ocf_vbdev_head = TAILQ_HEAD_INITIALIZER(g_ocf_vbdev_head); @@ -66,7 +62,6 @@ free_vbdev(struct vbdev_ocf *vbdev) return; } - pthread_mutex_destroy(&vbdev->_lock); free(vbdev->name); free(vbdev->cache.name); free(vbdev->core.name); @@ -327,7 +322,7 @@ io_handle(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io) goto fail; } - ocf_io_set_queue(io, ocf_queue_get_id(qctx->queue)); + ocf_io_set_queue(io, qctx->queue); data = vbdev_ocf_data_from_spdk_io(bdev_io); if (!data) { @@ -537,58 +532,40 @@ static int queue_poll(void *opaque) } } -/* Find queue index that is not taken */ -static int -get_free_queue_id(struct vbdev_ocf *vbdev) +/* Called during ocf_submit_io, ocf_purge* + * and any other requests that need to submit io */ +static void +vbdev_ocf_ctx_queue_kick(ocf_queue_t q) { - struct vbdev_ocf_qcxt *qctx; - int i, tmp; - - for (i = 1; i < (int)vbdev->cfg.cache.io_queues; i++) { - tmp = i; - TAILQ_FOREACH(qctx, &vbdev->queues, tailq) { - tmp = ocf_queue_get_id(qctx->queue); - if (tmp == i) { - tmp = -1; - break; - } - } - if (tmp > 0) { - return i; - } - } - - return -1; } +/* OCF queue deinitialization + * Called at ocf_cache_stop */ +static void +vbdev_ocf_ctx_queue_stop(ocf_queue_t q) +{ +} + +/* Queue ops is an interface for running queue thread + * stop() operation in called just before queue gets destroyed */ +const struct ocf_queue_ops queue_ops = { + .kick_sync = vbdev_ocf_ctx_queue_kick, + .kick = vbdev_ocf_ctx_queue_kick, + .stop = vbdev_ocf_ctx_queue_stop, +}; + /* Called on cache vbdev creation at every thread - * We determine on which OCF queue IOs from this thread will be running - * and allocate resources for that queue - * This is also where queue poller gets registered */ + * We allocate OCF queues here and SPDK poller for it */ static int io_device_create_cb(void *io_device, void *ctx_buf) { struct vbdev_ocf *vbdev = io_device; struct vbdev_ocf_qcxt *qctx = ctx_buf; - int queue_id = 0, rc; + int rc; - /* Modifying state of vbdev->queues needs to be synchronous - * We use vbdev private lock to achive that */ - pthread_mutex_lock(&vbdev->_lock); - - queue_id = get_free_queue_id(vbdev); - - if (queue_id < 0) { - SPDK_ERRLOG("OCF queues count is too small, try to allocate more than %d\n", - vbdev->cfg.cache.io_queues); - rc = -EINVAL; - goto end; - } - - rc = ocf_cache_get_queue(vbdev->ocf_cache, queue_id, &qctx->queue); + rc = ocf_queue_create(vbdev->ocf_cache, &qctx->queue, &queue_ops); if (rc) { - SPDK_ERRLOG("Could not get OCF queue #%d\n", queue_id); - goto end; + return rc; } ocf_queue_set_priv(qctx->queue, qctx); @@ -598,10 +575,6 @@ io_device_create_cb(void *io_device, void *ctx_buf) qctx->core_ch = spdk_bdev_get_io_channel(vbdev->core.desc); qctx->poller = spdk_poller_register(queue_poll, qctx, 0); - TAILQ_INSERT_TAIL(&vbdev->queues, qctx, tailq); - -end: - pthread_mutex_unlock(&vbdev->_lock); return rc; } @@ -616,10 +589,7 @@ io_device_destroy_cb(void *io_device, void *ctx_buf) spdk_put_io_channel(qctx->cache_ch); spdk_put_io_channel(qctx->core_ch); spdk_poller_unregister(&qctx->poller); - - pthread_mutex_lock(&qctx->vbdev->_lock); - TAILQ_REMOVE(&qctx->vbdev->queues, qctx, tailq); - pthread_mutex_unlock(&qctx->vbdev->_lock); + ocf_queue_put(qctx->queue); } /* Start OCF cache and register vbdev_ocf at bdev layer */ @@ -697,11 +667,6 @@ init_vbdev_config(struct vbdev_ocf *vbdev) cfg->cache.backfill.max_queue_size = 65536; cfg->cache.backfill.queue_unblock_size = 60000; - /* At this moment OCF queues count is static - * so we choose some value for it - * It has to be bigger than SPDK thread count */ - cfg->cache.io_queues = g_queues_count; - /* TODO [cache line size] */ cfg->device.cache_line_size = ocf_cache_line_size_4; cfg->device.force = true; @@ -744,8 +709,6 @@ init_vbdev(const char *vbdev_name, vbdev->core.parent = vbdev; vbdev->cache.is_cache = true; vbdev->core.is_cache = false; - pthread_mutex_init(&vbdev->_lock, NULL); - TAILQ_INIT(&vbdev->queues); if (cache_mode_name) { vbdev->cfg.cache.cache_mode diff --git a/lib/bdev/ocf/vbdev_ocf.h b/lib/bdev/ocf/vbdev_ocf.h index 93034b173..627daa521 100644 --- a/lib/bdev/ocf/vbdev_ocf.h +++ b/lib/bdev/ocf/vbdev_ocf.h @@ -130,13 +130,6 @@ struct vbdev_ocf { /* Link to global list of this type structures */ TAILQ_ENTRY(vbdev_ocf) tailq; - - /* List of queues contexts - * New items are added at io_channel creation */ - TAILQ_HEAD(, vbdev_ocf_qcxt) queues; - - /* Private per-bdev lock */ - pthread_mutex_t _lock; }; int vbdev_ocf_construct( diff --git a/lib/bdev/ocf/volume.c b/lib/bdev/ocf/volume.c index c685c03ac..b0209fb76 100644 --- a/lib/bdev/ocf/volume.c +++ b/lib/bdev/ocf/volume.c @@ -191,7 +191,7 @@ vbdev_ocf_volume_submit_io_cb(struct spdk_bdev_io *bdev_io, bool success, void * "base returned error on io submission: %d\n", io_ctx->error); } - if (io->io_queue == 0 && io_ctx->ch != NULL) { + if (io->io_queue == NULL && io_ctx->ch != NULL) { spdk_put_io_channel(io_ctx->ch); } @@ -211,8 +211,8 @@ prepare_submit(struct ocf_io *io) struct ocf_io_ctx *io_ctx = ocf_get_io_ctx(io); struct vbdev_ocf_qcxt *qctx; struct vbdev_ocf_base *base; - ocf_queue_t q; - int rc; + ocf_queue_t q = io->io_queue; + int rc = 0; io_ctx->rq_cnt++; if (io_ctx->rq_cnt != 1) { @@ -222,12 +222,9 @@ prepare_submit(struct ocf_io *io) vbdev_ocf_volume_io_get(io); base = *((struct vbdev_ocf_base **)ocf_volume_get_priv(io->volume)); - if (io->io_queue == 0) { - /* In SPDK we never set queue id to 0 - * but OCF sometimes gives it to us (not a bug) - * In such cases we cannot determine on which queue we are now - * So to get io channel that is usually passed as queue context - * we have to reallocate it using global method */ + if (io->io_queue == NULL) { + /* In case IO is initiated by OCF, queue is unknown + * so we have to get io channel ourselves */ io_ctx->ch = spdk_bdev_get_io_channel(base->desc); if (io_ctx->ch == NULL) { return -EPERM; @@ -235,13 +232,11 @@ prepare_submit(struct ocf_io *io) return 0; } - rc = ocf_cache_get_queue(base->parent->ocf_cache, io->io_queue, &q); - if (rc) { - SPDK_ERRLOG("Could not get queue #%d\n", io->io_queue); - return rc; + qctx = ocf_queue_get_priv(q); + if (qctx == NULL) { + return -EFAULT; } - qctx = ocf_queue_get_priv(q); if (base->is_cache) { io_ctx->ch = qctx->cache_ch; } else { diff --git a/ocf b/ocf index 276d91fcd..e23550047 160000 --- a/ocf +++ b/ocf @@ -1 +1 @@ -Subproject commit 276d91fcd7ca693fe093eb08d801b3c46df50cbf +Subproject commit e235500472c18a9e0687608d94cc542eaeeeb7a2