diff --git a/doc/HOME.md b/doc/HOME.md index 5efa7ca..3129928 100644 --- a/doc/HOME.md +++ b/doc/HOME.md @@ -90,7 +90,7 @@ int my_cache_init(void) { int result; - result ocf_ctx_init(&ctx, &ctx_ops) + result = ocf_ctx_create(&ctx, &ctx_ops) if (result) { /* Cannot initialze context of OCF library */ return result; @@ -116,7 +116,7 @@ int my_cache_init(void) err: /* In case of failure we destroy context and propagate error code */ - ocf_ctx_exit(ctx); + ocf_ctx_put(ctx); return result; } diff --git a/example/simple/src/ctx.c b/example/simple/src/ctx.c index adcc15d..610a1e2 100644 --- a/example/simple/src/ctx.c +++ b/example/simple/src/ctx.c @@ -278,13 +278,13 @@ int ctx_init(ocf_ctx_t *ctx) { int ret; - ret = ocf_ctx_init(ctx, &ctx_cfg); + ret = ocf_ctx_create(ctx, &ctx_cfg); if (ret) return ret; ret = volume_init(*ctx); if (ret) { - ocf_ctx_exit(*ctx); + ocf_ctx_put(*ctx); return ret; } @@ -298,5 +298,5 @@ int ctx_init(ocf_ctx_t *ctx) void ctx_cleanup(ocf_ctx_t ctx) { volume_cleanup(ctx); - ocf_ctx_exit(ctx); + ocf_ctx_put(ctx); } diff --git a/inc/ocf_ctx.h b/inc/ocf_ctx.h index b729faf..d97c1c3 100644 --- a/inc/ocf_ctx.h +++ b/inc/ocf_ctx.h @@ -285,24 +285,27 @@ int ocf_ctx_volume_create(ocf_ctx_t ctx, ocf_volume_t *volume, struct ocf_volume_uuid *uuid, uint8_t type_id); /** - * @brief Initialize OCF context + * @brief Create and initialize OCF context * * @param[out] ctx OCF context * @param[in] ops OCF context operations * * @return Zero when success, otherwise an error */ -int ocf_ctx_init(ocf_ctx_t *ctx, const struct ocf_ctx_config *cfg); +int ocf_ctx_create(ocf_ctx_t *ctx, const struct ocf_ctx_config *cfg); /** - * @brief De-Initialize OCF context + * @brief Increase reference counter of ctx * * @param[in] ctx OCF context - * - * @note Precondition is stopping all cache instances - * - * @return Zero when success, otherwise an error */ -int ocf_ctx_exit(ocf_ctx_t ctx); +void ocf_ctx_get(ocf_ctx_t ctx); + +/** + * @brief Decrease reference counter of ctx + * + * @param[in] ctx OCF context + */ +void ocf_ctx_put(ocf_ctx_t ctx); #endif /* __OCF_CTX_H__ */ diff --git a/src/mngt/ocf_mngt_cache.c b/src/mngt/ocf_mngt_cache.c index 60b2561..cf60718 100644 --- a/src/mngt/ocf_mngt_cache.c +++ b/src/mngt/ocf_mngt_cache.c @@ -1216,6 +1216,8 @@ static int _ocf_mngt_cache_start(ocf_ctx_t ctx, ocf_cache_t *cache, if (result) goto _cache_mng_init_instance_ERROR; + ocf_ctx_get(ctx); + if (params.locked) { /* Increment reference counter to match cache_lock / cache_unlock convention. User is expected to call diff --git a/src/mngt/ocf_mngt_common.c b/src/mngt/ocf_mngt_common.c index 9a6e816..37daa8f 100644 --- a/src/mngt/ocf_mngt_common.c +++ b/src/mngt/ocf_mngt_common.c @@ -119,11 +119,15 @@ void cache_mng_core_remove_from_cache(struct ocf_cache *cache, int core_id) void ocf_mngt_cache_put(ocf_cache_t cache) { + ocf_ctx_t ctx; + OCF_CHECK_NULL(cache); if (ocf_refcnt_dec(&cache->refcnt.cache) == 0) { + ctx = cache->owner; ocf_metadata_deinit(cache); env_vfree(cache); + ocf_ctx_put(ctx); } } diff --git a/src/ocf_ctx.c b/src/ocf_ctx.c index 2fb3fc2..00a0cbf 100644 --- a/src/ocf_ctx.c +++ b/src/ocf_ctx.c @@ -114,7 +114,7 @@ int ocf_ctx_volume_create(ocf_ctx_t ctx, ocf_volume_t *volume, /* * */ -int ocf_ctx_init(ocf_ctx_t *ctx, const struct ocf_ctx_config *cfg) +int ocf_ctx_create(ocf_ctx_t *ctx, const struct ocf_ctx_config *cfg) { ocf_ctx_t ocf_ctx; int ret; @@ -127,6 +127,7 @@ int ocf_ctx_init(ocf_ctx_t *ctx, const struct ocf_ctx_config *cfg) return -ENOMEM; INIT_LIST_HEAD(&ocf_ctx->caches); + env_atomic_set(&ocf_ctx->ref_count, 1); ret = env_mutex_init(&ocf_ctx->lock); if (ret) goto err_ctx; @@ -166,25 +167,30 @@ err_ctx: /* * */ -int ocf_ctx_exit(ocf_ctx_t ctx) +void ocf_ctx_get(ocf_ctx_t ctx) { - int result = 0; - OCF_CHECK_NULL(ctx); - /* Check if caches are setup */ + env_atomic_inc(&ctx->ref_count); +} + +/* + * + */ +void ocf_ctx_put(ocf_ctx_t ctx) +{ + OCF_CHECK_NULL(ctx); + + if (env_atomic_dec_return(&ctx->ref_count)) + return; + env_mutex_lock(&ctx->lock); - if (!list_empty(&ctx->caches)) - result = -EEXIST; + ENV_BUG_ON(!list_empty(&ctx->caches)); env_mutex_unlock(&ctx->lock); - if (result) - return result; ocf_mngt_core_pool_deinit(ctx); ocf_core_volume_type_deinit(ctx); ocf_utils_deinit(ctx); ocf_logger_close(&ctx->logger); env_free(ctx); - - return 0; } diff --git a/src/ocf_ctx_priv.h b/src/ocf_ctx_priv.h index f8f6143..c16fc36 100644 --- a/src/ocf_ctx_priv.h +++ b/src/ocf_ctx_priv.h @@ -20,6 +20,7 @@ struct ocf_ctx { const struct ocf_ctx_config *cfg; struct ocf_logger logger; struct ocf_volume_type *volume_type[OCF_VOLUME_TYPE_MAX]; + env_atomic ref_count; env_mutex lock; struct list_head caches; struct { diff --git a/tests/functional/pyocf/types/ctx.py b/tests/functional/pyocf/types/ctx.py index 775eae5..7b4371d 100644 --- a/tests/functional/pyocf/types/ctx.py +++ b/tests/functional/pyocf/types/ctx.py @@ -51,7 +51,7 @@ class OcfCtx: logger_priv=cast(pointer(logger.get_priv()), c_void_p), ) - result = self.lib.ocf_ctx_init(byref(self.ctx_handle), byref(self.cfg)) + result = self.lib.ocf_ctx_create(byref(self.ctx_handle), byref(self.cfg)) if result != 0: raise OcfError("Context initialization failed", result) @@ -95,9 +95,7 @@ class OcfCtx: self.stop_caches() self.cleanup_volume_types() - result = self.lib.ocf_ctx_exit(self.ctx_handle) - if result != 0: - raise OcfError("Failed quitting OcfCtx", result) + self.lib.ocf_ctx_put(self.ctx_handle) self.cfg = None self.logger = None