From 61414f889e6ce7417bf24daa8343facd9b1e803c Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 29 May 2019 14:31:48 +0200 Subject: [PATCH] Introduce OCF IO allocator Signed-off-by: Robert Baldyga --- inc/ocf_types.h | 2 +- src/ocf_ctx.c | 14 ++++++-- src/ocf_io.c | 48 ++++++++++++++++++++++---- src/ocf_io_priv.h | 5 +-- src/ocf_volume.c | 17 ++++++---- src/ocf_volume_priv.h | 10 ++++-- src/utils/utils_cleaner.c | 20 +++++------ src/utils/utils_io_allocator.h | 62 ++++++++++++++++++++++++++++++++++ 8 files changed, 147 insertions(+), 31 deletions(-) create mode 100644 src/utils/utils_io_allocator.h diff --git a/inc/ocf_types.h b/inc/ocf_types.h index 95a55e8..fb02373 100644 --- a/inc/ocf_types.h +++ b/inc/ocf_types.h @@ -65,7 +65,7 @@ struct ocf_volume_type; /** * @brief handle to volume type */ -typedef const struct ocf_volume_type *ocf_volume_type_t; +typedef struct ocf_volume_type *ocf_volume_type_t; /** * @brief handle to volume uuid diff --git a/src/ocf_ctx.c b/src/ocf_ctx.c index c1a7310..113d631 100644 --- a/src/ocf_ctx.c +++ b/src/ocf_ctx.c @@ -15,8 +15,9 @@ /* * */ -int ocf_ctx_register_volume_type(ocf_ctx_t ctx, uint8_t type_id, - const struct ocf_volume_properties *properties) +int ocf_ctx_register_volume_type_extended(ocf_ctx_t ctx, uint8_t type_id, + const struct ocf_volume_properties *properties, + const struct ocf_volume_extended *extended) { int result = 0; @@ -31,7 +32,7 @@ int ocf_ctx_register_volume_type(ocf_ctx_t ctx, uint8_t type_id, goto err; } - ocf_volume_type_init(&ctx->volume_type[type_id], properties); + ocf_volume_type_init(&ctx->volume_type[type_id], properties, extended); if (!ctx->volume_type[type_id]) result = -EINVAL; @@ -50,6 +51,13 @@ err: return result; } +int ocf_ctx_register_volume_type(ocf_ctx_t ctx, uint8_t type_id, + const struct ocf_volume_properties *properties) +{ + return ocf_ctx_register_volume_type_extended(ctx, type_id, + properties, NULL); +} + /* * */ diff --git a/src/ocf_io.c b/src/ocf_io.c index fd12b35..5e89bf8 100644 --- a/src/ocf_io.c +++ b/src/ocf_io.c @@ -6,6 +6,7 @@ #include "ocf/ocf.h" #include "ocf_io_priv.h" #include "ocf_volume_priv.h" +#include "utils/utils_io_allocator.h" /* * This is io allocator dedicated for bottom devices. @@ -26,17 +27,49 @@ * +-------------------------+ <---------------- */ -#define OCF_IO_TOTAL_SIZE(priv_size) \ +#define OCF_IO_TOTAL(priv_size) \ (sizeof(struct ocf_io_internal) + priv_size) -env_allocator *ocf_io_allocator_create(uint32_t size, const char *name) +static int ocf_io_allocator_default_init(ocf_io_allocator_t allocator, + uint32_t priv_size, const char *name) { - return env_allocator_create(OCF_IO_TOTAL_SIZE(size), name); + allocator->priv = env_allocator_create(OCF_IO_TOTAL(priv_size), name); + if (!allocator->priv) + return -OCF_ERR_NO_MEM; + + return 0; } -void ocf_io_allocator_destroy(env_allocator *allocator) +static void ocf_io_allocator_default_deinit(ocf_io_allocator_t allocator) { - env_allocator_destroy(allocator); + env_allocator_destroy(allocator->priv); + allocator->priv = NULL; +} + +static void *ocf_io_allocator_default_new(ocf_io_allocator_t allocator, + ocf_volume_t volume, ocf_queue_t queue, + uint64_t addr, uint32_t bytes, uint32_t dir) +{ + return env_allocator_new(allocator->priv); +} + +static void ocf_io_allocator_default_del(ocf_io_allocator_t allocator, void *obj) +{ + env_allocator_del(allocator->priv, obj); +} + +const struct ocf_io_allocator_type type_default = { + .ops = { + .allocator_init = ocf_io_allocator_default_init, + .allocator_deinit = ocf_io_allocator_default_deinit, + .allocator_new = ocf_io_allocator_default_new, + .allocator_del = ocf_io_allocator_default_del, + }, +}; + +ocf_io_allocator_type_t ocf_io_allocator_get_type_default(void) +{ + return &type_default; } /* @@ -57,7 +90,8 @@ struct ocf_io *ocf_io_new(ocf_volume_t volume, ocf_queue_t queue, if (!ocf_refcnt_inc(&volume->refcnt)) return NULL; - ioi = env_allocator_new(volume->type->allocator); + ioi = ocf_io_allocator_new(&volume->type->allocator, volume, queue, + addr, bytes, dir); if (!ioi) { ocf_refcnt_dec(&volume->refcnt); return NULL; @@ -116,7 +150,7 @@ void ocf_io_put(struct ocf_io *io) ocf_refcnt_dec(&ioi->meta.volume->refcnt); - env_allocator_del(ioi->meta.volume->type->allocator, (void *)ioi); + ocf_io_allocator_del(&ioi->meta.volume->type->allocator, (void *)ioi); } ocf_volume_t ocf_io_get_volume(struct ocf_io *io) diff --git a/src/ocf_io_priv.h b/src/ocf_io_priv.h index 42ce735..4735b5c 100644 --- a/src/ocf_io_priv.h +++ b/src/ocf_io_priv.h @@ -8,6 +8,7 @@ #include "ocf/ocf.h" #include "ocf_request.h" +#include "utils/utils_io_allocator.h" struct ocf_io_meta { ocf_volume_t volume; @@ -21,9 +22,9 @@ struct ocf_io_internal { struct ocf_io io; }; -env_allocator *ocf_io_allocator_create(uint32_t size, const char *name); +int ocf_io_allocator_init(ocf_io_allocator_t allocator, ocf_io_allocator_type_t type, + uint32_t priv_size, const char *name); -void ocf_io_allocator_destroy(env_allocator *allocator); struct ocf_io *ocf_io_new(ocf_volume_t volume, ocf_queue_t queue, uint64_t addr, uint32_t bytes, uint32_t dir, diff --git a/src/ocf_volume.c b/src/ocf_volume.c index a141059..404b8c1 100644 --- a/src/ocf_volume.c +++ b/src/ocf_volume.c @@ -16,9 +16,11 @@ */ int ocf_volume_type_init(struct ocf_volume_type **type, - const struct ocf_volume_properties *properties) + const struct ocf_volume_properties *properties, + const struct ocf_volume_extended *extended) { const struct ocf_volume_ops *ops = &properties->ops; + ocf_io_allocator_type_t allocator_type; struct ocf_volume_type *new_type; int ret; @@ -34,12 +36,15 @@ int ocf_volume_type_init(struct ocf_volume_type **type, if (!new_type) return -OCF_ERR_NO_MEM; - new_type->allocator = ocf_io_allocator_create( + if (extended && extended->allocator_type) + allocator_type = extended->allocator_type; + else + allocator_type = ocf_io_allocator_get_type_default(); + + ret = ocf_io_allocator_init(&new_type->allocator, allocator_type, properties->io_priv_size, properties->name); - if (!new_type->allocator) { - ret = -OCF_ERR_NO_MEM; + if (ret) goto err; - } new_type->properties = properties; @@ -54,7 +59,7 @@ err: void ocf_volume_type_deinit(struct ocf_volume_type *type) { - ocf_io_allocator_destroy(type->allocator); + ocf_io_allocator_deinit(&type->allocator); env_free(type); } diff --git a/src/ocf_volume_priv.h b/src/ocf_volume_priv.h index e2b9249..1e51a37 100644 --- a/src/ocf_volume_priv.h +++ b/src/ocf_volume_priv.h @@ -9,10 +9,15 @@ #include "ocf_env.h" #include "ocf_io_priv.h" #include "utils/utils_refcnt.h" +#include "utils/utils_io_allocator.h" + +struct ocf_volume_extended { + ocf_io_allocator_type_t allocator_type; +}; struct ocf_volume_type { const struct ocf_volume_properties *properties; - env_allocator *allocator; + struct ocf_io_allocator allocator; }; struct ocf_volume { @@ -31,7 +36,8 @@ struct ocf_volume { }; int ocf_volume_type_init(struct ocf_volume_type **type, - const struct ocf_volume_properties *properties); + const struct ocf_volume_properties *properties, + const struct ocf_volume_extended *extended); void ocf_volume_type_deinit(struct ocf_volume_type *type); diff --git a/src/utils/utils_cleaner.c b/src/utils/utils_cleaner.c index c20265e..e9a2f08 100644 --- a/src/utils/utils_cleaner.c +++ b/src/utils/utils_cleaner.c @@ -658,16 +658,6 @@ static int _ocf_cleaner_fire_cache(struct ocf_request *req) cache_stats = &cache->core[iter->core_id]. counters->cache_blocks; - io = ocf_new_cache_io(cache, req->io_queue, - addr, ocf_line_size(cache), - OCF_READ, part_id, 0); - if (!io) { - /* Allocation error */ - iter->invalid = true; - _ocf_cleaner_set_error(req); - continue; - } - OCF_DEBUG_PARAM(req->cache, "Cache read, line = %u", iter->coll_idx); @@ -680,6 +670,16 @@ static int _ocf_cleaner_fire_cache(struct ocf_request *req) part_id = ocf_metadata_get_partition_id(cache, iter->coll_idx); + io = ocf_new_cache_io(cache, req->io_queue, + addr, ocf_line_size(cache), + OCF_READ, part_id, 0); + if (!io) { + /* Allocation error */ + iter->invalid = true; + _ocf_cleaner_set_error(req); + continue; + } + ocf_io_set_cmpl(io, iter, req, _ocf_cleaner_cache_io_cmpl); err = ocf_io_set_data(io, req->data, offset); if (err) { diff --git a/src/utils/utils_io_allocator.h b/src/utils/utils_io_allocator.h new file mode 100644 index 0000000..2a7bae2 --- /dev/null +++ b/src/utils/utils_io_allocator.h @@ -0,0 +1,62 @@ +/* + * Copyright(c) 2019 Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause-Clear + */ + +#ifndef __UTILS_IO_ALLOCATOR_H__ +#define __UTILS_IO_ALLOCATOR_H__ + +#include "ocf/ocf_types.h" + +typedef struct ocf_io_allocator *ocf_io_allocator_t; + +struct ocf_io_allocator_ops { + int (*allocator_init)(ocf_io_allocator_t allocator, + uint32_t priv_size, const char *name); + void (*allocator_deinit)(ocf_io_allocator_t allocator); + void *(*allocator_new)(ocf_io_allocator_t allocator, + ocf_volume_t volume, ocf_queue_t queue, + uint64_t addr, uint32_t bytes, uint32_t dir); + void (*allocator_del)(ocf_io_allocator_t allocator, void *obj); +}; + +struct ocf_io_allocator_type { + struct ocf_io_allocator_ops ops; +}; + +typedef const struct ocf_io_allocator_type *ocf_io_allocator_type_t; + +struct ocf_io_allocator { + const struct ocf_io_allocator_type *type; + void *priv; +}; + +static inline void *ocf_io_allocator_new(ocf_io_allocator_t allocator, + ocf_volume_t volume, ocf_queue_t queue, + uint64_t addr, uint32_t bytes, uint32_t dir) +{ + return allocator->type->ops.allocator_new(allocator, volume, queue, + addr, bytes, dir); +} + +static inline void ocf_io_allocator_del(ocf_io_allocator_t allocator, void *obj) +{ + allocator->type->ops.allocator_del(allocator, obj); +} + +static inline int ocf_io_allocator_init(ocf_io_allocator_t allocator, + ocf_io_allocator_type_t type, uint32_t size, const char *name) + +{ + allocator->type = type; + return allocator->type->ops.allocator_init(allocator, size, name); +} + +static inline void ocf_io_allocator_deinit(ocf_io_allocator_t allocator) +{ + allocator->type->ops.allocator_deinit(allocator); +} + +ocf_io_allocator_type_t ocf_io_allocator_get_type_default(void); + +#endif /* __UTILS_IO_ALLOCATOR__ */