@@ -5,6 +5,8 @@
|
||||
*/
|
||||
|
||||
#include "ocf/ocf.h"
|
||||
#include "ocf_env.h"
|
||||
#include "ocf_env_refcnt.h"
|
||||
#include "ocf_mngt_common.h"
|
||||
#include "ocf_mngt_core_priv.h"
|
||||
#include "../ocf_priv.h"
|
||||
@@ -20,8 +22,8 @@
|
||||
#include "../utils/utils_cache_line.h"
|
||||
#include "../utils/utils_parallelize.h"
|
||||
#include "../utils/utils_pipeline.h"
|
||||
#include "../utils/utils_refcnt.h"
|
||||
#include "../utils/utils_async_lock.h"
|
||||
#include "../utils/utils_cleaner.h"
|
||||
#include "../concurrency/ocf_concurrency.h"
|
||||
#include "../concurrency/ocf_metadata_concurrency.h"
|
||||
#include "../ocf_lru.h"
|
||||
@@ -188,7 +190,7 @@ static void __init_partitions(ocf_cache_t cache)
|
||||
|
||||
/* Add other partition to the cache and make it as dummy */
|
||||
for (i_part = 0; i_part < OCF_USER_IO_CLASS_MAX; i_part++) {
|
||||
ocf_refcnt_freeze(&cache->user_parts[i_part].cleaning.counter);
|
||||
env_refcnt_freeze(&cache->user_parts[i_part].cleaning.counter);
|
||||
|
||||
if (i_part == PARTITION_DEFAULT)
|
||||
continue;
|
||||
@@ -217,21 +219,30 @@ static void _init_parts_attached(ocf_pipeline_t pipeline, void *priv,
|
||||
|
||||
static ocf_error_t __init_cleaning_policy(ocf_cache_t cache)
|
||||
{
|
||||
int result;
|
||||
int i;
|
||||
|
||||
OCF_ASSERT_PLUGGED(cache);
|
||||
|
||||
ocf_refcnt_init(&cache->cleaner.refcnt);
|
||||
result = env_refcnt_init(&cache->cleaner.refcnt, "cleaner",
|
||||
sizeof("cleaner"));
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
for (i = 0; i < ocf_cleaning_max; i++)
|
||||
ocf_cleaning_setup(cache, i);
|
||||
|
||||
return ocf_cleaning_initialize(cache, cache->cleaner.policy, false);
|
||||
result = ocf_cleaning_initialize(cache, cache->cleaner.policy, false);
|
||||
if (result)
|
||||
env_refcnt_deinit(&cache->cleaner.refcnt);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void __deinit_cleaning_policy(ocf_cache_t cache)
|
||||
{
|
||||
ocf_cleaning_deinitialize(cache);
|
||||
env_refcnt_deinit(&cache->cleaner.refcnt);
|
||||
}
|
||||
|
||||
static void __setup_promotion_policy(ocf_cache_t cache)
|
||||
@@ -425,7 +436,9 @@ static void _ocf_mngt_load_add_cores(ocf_pipeline_t pipeline,
|
||||
* Attach bottom device to core structure
|
||||
* in cache
|
||||
*/
|
||||
env_refcnt_freeze(&tvolume->refcnt);
|
||||
ocf_volume_move(&core->volume, tvolume);
|
||||
env_refcnt_unfreeze(&tvolume->refcnt);
|
||||
ocf_mngt_core_pool_remove(cache->owner, tvolume);
|
||||
|
||||
core->opened = true;
|
||||
@@ -720,6 +733,12 @@ static void _ocf_mngt_load_init_cleaning(ocf_pipeline_t pipeline,
|
||||
ocf_cache_t cache = context->cache;
|
||||
ocf_error_t result;
|
||||
|
||||
result = env_refcnt_init(&cache->cleaner.refcnt, "cleaner", sizeof("cleaner"));
|
||||
if (result) {
|
||||
ocf_cache_log(cache, log_err, "Cannot initialize cleaner refcount\n");
|
||||
OCF_PL_FINISH_RET(pipeline, result);
|
||||
}
|
||||
|
||||
if (context->metadata.shutdown_status == ocf_metadata_clean_shutdown) {
|
||||
/* Cleaning policy structures have been loaded so no need to populate
|
||||
them for the second time */
|
||||
@@ -827,7 +846,8 @@ static int _ocf_mngt_init_new_cache(struct ocf_cache_mngt_init_params *params,
|
||||
char *new_cache_name)
|
||||
{
|
||||
ocf_cache_t cache = env_vzalloc(sizeof(*cache));
|
||||
int result;
|
||||
int result = 0;
|
||||
int i = 0;
|
||||
|
||||
if (!cache) {
|
||||
ocf_log(params->ctx, log_err, "Failed to allocate cache %s\n",
|
||||
@@ -843,13 +863,37 @@ static int _ocf_mngt_init_new_cache(struct ocf_cache_mngt_init_params *params,
|
||||
goto alloc_err;
|
||||
}
|
||||
|
||||
result = env_refcnt_init(&cache->refcnt.cache, "cache", sizeof("cache"));
|
||||
if (result)
|
||||
goto lock_init_err;
|
||||
|
||||
result = env_refcnt_init(&cache->refcnt.dirty, "dirty", sizeof("dirty"));
|
||||
if (result)
|
||||
goto dirty_refcnt_err;
|
||||
|
||||
result = env_refcnt_init(&cache->refcnt.metadata, "metadata", sizeof("metadata"));
|
||||
if (result)
|
||||
goto metadata_refcnt_err;
|
||||
|
||||
result = env_refcnt_init(&cache->refcnt.d2c, "d2c", sizeof("d2c"));
|
||||
if (result)
|
||||
goto d2c_refcnt_err;
|
||||
|
||||
for (i = 0; i < OCF_USER_IO_CLASS_MAX; i++) {
|
||||
result = env_refcnt_init(&cache->user_parts[i].cleaning.counter,
|
||||
"cleaning", sizeof("cleaning"));
|
||||
if (result)
|
||||
goto cleaning_refcnt_err;
|
||||
env_atomic_set(&cache->user_parts[i].cleaning.cleaner_running, 0);
|
||||
}
|
||||
|
||||
/* Lock cache during setup - this trylock should always succeed */
|
||||
result = ocf_mngt_cache_trylock(cache);
|
||||
if (result) {
|
||||
ocf_log(params->ctx, log_crit,
|
||||
"Failed to lock the newly created cache %s\n",
|
||||
new_cache_name);
|
||||
goto lock_init_err;
|
||||
goto cleaning_refcnt_err;
|
||||
}
|
||||
|
||||
if (env_mutex_init(&cache->flush_mutex)) {
|
||||
@@ -869,7 +913,7 @@ static int _ocf_mngt_init_new_cache(struct ocf_cache_mngt_init_params *params,
|
||||
goto mutex_err;
|
||||
}
|
||||
|
||||
result = !ocf_refcnt_inc(&cache->refcnt.cache);
|
||||
result = !env_refcnt_inc(&cache->refcnt.cache);
|
||||
if (result) {
|
||||
ocf_log(params->ctx, log_crit,
|
||||
"Failed to increment %s refcnt\n",
|
||||
@@ -877,10 +921,8 @@ static int _ocf_mngt_init_new_cache(struct ocf_cache_mngt_init_params *params,
|
||||
goto cache_refcnt_inc_err;
|
||||
}
|
||||
|
||||
/* start with freezed metadata ref counter to indicate detached device*/
|
||||
ocf_refcnt_freeze(&cache->refcnt.metadata);
|
||||
|
||||
ocf_refcnt_init(&cache->refcnt.d2c);
|
||||
/* start with frozen metadata ref counter to indicate detached device*/
|
||||
env_refcnt_freeze(&cache->refcnt.metadata);
|
||||
|
||||
env_atomic_set(&(cache->last_access_ms),
|
||||
env_ticks_to_msecs(env_get_tick_count()));
|
||||
@@ -898,6 +940,17 @@ mutex_err:
|
||||
env_mutex_destroy(&cache->flush_mutex);
|
||||
lock_err:
|
||||
ocf_mngt_cache_unlock(cache);
|
||||
cleaning_refcnt_err:
|
||||
for (; i >= 0; i--) {
|
||||
env_refcnt_deinit(&cache->user_parts[i].cleaning.counter);
|
||||
}
|
||||
env_refcnt_deinit(&cache->refcnt.d2c);
|
||||
d2c_refcnt_err:
|
||||
env_refcnt_deinit(&cache->refcnt.metadata);
|
||||
metadata_refcnt_err:
|
||||
env_refcnt_deinit(&cache->refcnt.dirty);
|
||||
dirty_refcnt_err:
|
||||
env_refcnt_deinit(&cache->refcnt.cache);
|
||||
lock_init_err:
|
||||
ocf_mngt_cache_lock_deinit(cache);
|
||||
alloc_err:
|
||||
@@ -1377,8 +1430,10 @@ static void _ocf_mngt_cleaning_populate_init_complete(void *priv, int error)
|
||||
struct ocf_cache_attach_context *context = priv;
|
||||
ocf_cache_t cache = context->cache;
|
||||
|
||||
if (error)
|
||||
if (error) {
|
||||
env_refcnt_deinit(&cache->cleaner.refcnt);
|
||||
OCF_PL_FINISH_RET(context->pipeline, error);
|
||||
}
|
||||
|
||||
/* In initial cache state there is no dirty data, so all dirty data is
|
||||
considered to be flushed
|
||||
@@ -1459,6 +1514,7 @@ uint64_t ocf_mngt_get_ram_needed(ocf_cache_t cache,
|
||||
static void _ocf_mngt_init_handle_error(ocf_ctx_t ctx,
|
||||
struct ocf_cache_mngt_init_params *params)
|
||||
{
|
||||
int i;
|
||||
ocf_cache_t cache = params->cache;
|
||||
|
||||
if (!params->flags.cache_alloc)
|
||||
@@ -1471,6 +1527,14 @@ static void _ocf_mngt_init_handle_error(ocf_ctx_t ctx,
|
||||
if (params->flags.cache_locked)
|
||||
ocf_mngt_cache_unlock(cache);
|
||||
|
||||
for (i = 0; i < OCF_USER_IO_CLASS_MAX; i++)
|
||||
env_refcnt_deinit(&cache->user_parts[i].cleaning.counter);
|
||||
|
||||
env_refcnt_deinit(&cache->refcnt.d2c);
|
||||
env_refcnt_deinit(&cache->refcnt.metadata);
|
||||
env_refcnt_deinit(&cache->refcnt.dirty);
|
||||
env_refcnt_deinit(&cache->refcnt.cache);
|
||||
|
||||
ocf_mngt_cache_lock_deinit(cache);
|
||||
|
||||
if (params->flags.metadata_inited)
|
||||
@@ -1907,7 +1971,7 @@ static void _ocf_mngt_attach_post_init_finish(void *priv)
|
||||
struct ocf_cache_attach_context *context = priv;
|
||||
ocf_cache_t cache = context->cache;
|
||||
|
||||
ocf_refcnt_unfreeze(&cache->refcnt.d2c);
|
||||
env_refcnt_unfreeze(&cache->refcnt.d2c);
|
||||
|
||||
env_atomic_set(&cache->attach_pt, 0);
|
||||
|
||||
@@ -1925,10 +1989,10 @@ static void _ocf_mngt_attach_post_init(ocf_pipeline_t pipeline,
|
||||
env_atomic_set(&cache->attach_pt, 1);
|
||||
|
||||
ocf_cleaner_refcnt_unfreeze(cache);
|
||||
ocf_refcnt_unfreeze(&cache->refcnt.metadata);
|
||||
env_refcnt_unfreeze(&cache->refcnt.metadata);
|
||||
|
||||
ocf_refcnt_freeze(&cache->refcnt.d2c);
|
||||
ocf_refcnt_register_zero_cb(&cache->refcnt.d2c,
|
||||
env_refcnt_freeze(&cache->refcnt.d2c);
|
||||
env_refcnt_register_zero_cb(&cache->refcnt.d2c,
|
||||
_ocf_mngt_attach_post_init_finish, context);
|
||||
}
|
||||
|
||||
@@ -2081,22 +2145,14 @@ struct ocf_mngt_cache_unplug_context {
|
||||
int cache_write_error;
|
||||
};
|
||||
|
||||
static void ocf_mngt_cache_stop_wait_metadata_io_finish(void *priv)
|
||||
{
|
||||
struct ocf_mngt_cache_unplug_context *context = priv;
|
||||
|
||||
ocf_pipeline_next(context->pipeline);
|
||||
}
|
||||
|
||||
static void ocf_mngt_cache_stop_wait_metadata_io(ocf_pipeline_t pipeline,
|
||||
void *priv, ocf_pipeline_arg_t arg)
|
||||
{
|
||||
struct ocf_mngt_cache_unplug_context *context = priv;
|
||||
ocf_cache_t cache = context->cache;
|
||||
struct env_refcnt *refcnt = &context->cache->refcnt.metadata;
|
||||
|
||||
ocf_refcnt_freeze(&cache->refcnt.metadata);
|
||||
ocf_refcnt_register_zero_cb(&cache->refcnt.metadata,
|
||||
ocf_mngt_cache_stop_wait_metadata_io_finish, context);
|
||||
env_refcnt_freeze(refcnt);
|
||||
ocf_mngt_continue_pipeline_on_zero_refcnt(refcnt, context->pipeline);
|
||||
}
|
||||
|
||||
static void ocf_mngt_cache_stop_check_dirty(ocf_pipeline_t pipeline,
|
||||
@@ -2257,14 +2313,35 @@ static void ocf_mngt_cache_stop_put_io_queues(ocf_pipeline_t pipeline,
|
||||
ocf_pipeline_next(pipeline);
|
||||
}
|
||||
|
||||
static void _ocf_mngt_cache_dealloc(void *priv)
|
||||
{
|
||||
ocf_cache_t cache = priv;
|
||||
ocf_ctx_t ctx;
|
||||
unsigned i;
|
||||
|
||||
ctx = cache->owner;
|
||||
ocf_metadata_deinit(cache);
|
||||
|
||||
env_refcnt_deinit(&cache->refcnt.cache);
|
||||
env_refcnt_deinit(&cache->refcnt.dirty);
|
||||
env_refcnt_deinit(&cache->refcnt.metadata);
|
||||
for (i = 0; i < OCF_USER_IO_CLASS_MAX; i++)
|
||||
env_refcnt_deinit(&cache->user_parts[i].cleaning.counter);
|
||||
|
||||
env_vfree(cache);
|
||||
ocf_ctx_put(ctx);
|
||||
}
|
||||
|
||||
static void ocf_mngt_cache_remove(ocf_ctx_t ctx, ocf_cache_t cache)
|
||||
{
|
||||
/* Mark device uninitialized */
|
||||
ocf_refcnt_freeze(&cache->refcnt.cache);
|
||||
|
||||
/* Deinitialize locks */
|
||||
/* Deinitialize cache lock */
|
||||
ocf_mngt_cache_lock_deinit(cache);
|
||||
|
||||
/* Mark device uninitialized */
|
||||
env_refcnt_freeze(&cache->refcnt.cache);
|
||||
env_refcnt_register_zero_cb(&cache->refcnt.cache,
|
||||
_ocf_mngt_cache_dealloc, cache);
|
||||
|
||||
env_spinlock_destroy(&cache->io_queues_lock);
|
||||
|
||||
env_mutex_destroy(&cache->flush_mutex);
|
||||
@@ -2289,7 +2366,7 @@ static void ocf_mngt_cache_stop_finish(ocf_pipeline_t pipeline,
|
||||
ocf_mngt_cache_remove(context->ctx, cache);
|
||||
} else {
|
||||
/* undo metadata counter freeze */
|
||||
ocf_refcnt_unfreeze(&cache->refcnt.metadata);
|
||||
env_refcnt_unfreeze(&cache->refcnt.metadata);
|
||||
|
||||
env_bit_clear(ocf_cache_state_stopping, &cache->cache_state);
|
||||
env_bit_set(ocf_cache_state_running, &cache->cache_state);
|
||||
@@ -2446,7 +2523,7 @@ static void _ocf_mngt_standby_post_init(ocf_pipeline_t pipeline,
|
||||
struct ocf_cache_attach_context *context = priv;
|
||||
ocf_cache_t cache = context->cache;
|
||||
|
||||
ocf_refcnt_unfreeze(&cache->refcnt.metadata);
|
||||
env_refcnt_unfreeze(&cache->refcnt.metadata);
|
||||
|
||||
ocf_pipeline_next(pipeline);
|
||||
}
|
||||
@@ -2506,22 +2583,14 @@ struct ocf_cache_standby_detach_context {
|
||||
void *priv;
|
||||
};
|
||||
|
||||
static void _ocf_mngt_standby_detach_wait_metadata_io_finish(void *priv)
|
||||
{
|
||||
struct ocf_cache_standby_detach_context *context = priv;
|
||||
|
||||
ocf_pipeline_next(context->pipeline);
|
||||
}
|
||||
|
||||
static void _ocf_mngt_standby_detach_wait_metadata_io(ocf_pipeline_t pipeline,
|
||||
void *priv, ocf_pipeline_arg_t arg)
|
||||
{
|
||||
struct ocf_cache_standby_detach_context *context = priv;
|
||||
ocf_cache_t cache = context->cache;
|
||||
struct env_refcnt *refcnt = &context->cache->refcnt.metadata;
|
||||
|
||||
ocf_refcnt_freeze(&cache->refcnt.metadata);
|
||||
ocf_refcnt_register_zero_cb(&cache->refcnt.metadata,
|
||||
_ocf_mngt_standby_detach_wait_metadata_io_finish, context);
|
||||
env_refcnt_freeze(refcnt);
|
||||
ocf_mngt_continue_pipeline_on_zero_refcnt(refcnt, context->pipeline);
|
||||
}
|
||||
|
||||
static void _ocf_mngt_activate_set_cache_device(ocf_pipeline_t pipeline,
|
||||
@@ -2661,7 +2730,7 @@ static void _ocf_mngt_activate_handle_error(
|
||||
ocf_volume_deinit(&cache->device->volume);
|
||||
|
||||
if (context->flags.metadata_frozen)
|
||||
ocf_refcnt_unfreeze(&cache->refcnt.metadata);
|
||||
env_refcnt_unfreeze(&cache->refcnt.metadata);
|
||||
}
|
||||
|
||||
static void _ocf_mngt_cache_activate_finish(ocf_pipeline_t pipeline,
|
||||
@@ -2786,7 +2855,7 @@ static void ocf_mngt_stop_standby_stop_prepare(ocf_pipeline_t pipeline,
|
||||
struct ocf_mngt_cache_unplug_context *context = priv;
|
||||
ocf_cache_t cache = context->cache;
|
||||
|
||||
context->close_volume = !ocf_refcnt_frozen(&cache->refcnt.metadata);
|
||||
context->close_volume = !env_refcnt_frozen(&cache->refcnt.metadata);
|
||||
|
||||
ocf_pipeline_next(pipeline);
|
||||
}
|
||||
@@ -2832,7 +2901,7 @@ static void ocf_mngt_cache_standby_deinit_cache_volume(ocf_pipeline_t pipeline,
|
||||
struct ocf_mngt_cache_unplug_context *context = priv;
|
||||
ocf_cache_t cache = context->cache;
|
||||
|
||||
if (!ocf_refcnt_frozen(&cache->refcnt.metadata)) {
|
||||
if (!env_refcnt_frozen(&cache->refcnt.metadata)) {
|
||||
ocf_volume_deinit(&cache->device->volume);
|
||||
|
||||
env_vfree(cache->device);
|
||||
@@ -2992,7 +3061,7 @@ static void _ocf_mngt_cache_standby_activate(ocf_cache_t cache,
|
||||
if (!ocf_cache_is_standby(cache))
|
||||
OCF_CMPL_RET(cache, priv1, priv2, -OCF_ERR_CACHE_EXIST);
|
||||
|
||||
if (!ocf_refcnt_frozen(&cache->refcnt.metadata))
|
||||
if (!env_refcnt_frozen(&cache->refcnt.metadata))
|
||||
OCF_CMPL_RET(cache, priv1, priv2, OCF_ERR_STANDBY_ATTACHED);
|
||||
|
||||
result = ocf_pipeline_create(&pipeline, cache,
|
||||
@@ -3361,7 +3430,7 @@ void ocf_mngt_cache_standby_detach(ocf_cache_t cache,
|
||||
if (!ocf_cache_is_standby(cache))
|
||||
OCF_CMPL_RET(priv, -OCF_ERR_CACHE_EXIST);
|
||||
|
||||
if (ocf_refcnt_frozen(&cache->refcnt.metadata))
|
||||
if (env_refcnt_frozen(&cache->refcnt.metadata))
|
||||
OCF_CMPL_RET(priv, -OCF_ERR_INVAL);
|
||||
|
||||
_ocf_mngt_cache_standby_detach(cache, cmpl, priv);
|
||||
@@ -3753,21 +3822,14 @@ static void ocf_mngt_cache_detach_flush(ocf_pipeline_t pipeline,
|
||||
ocf_mngt_cache_flush(cache, ocf_mngt_cache_detach_flush_cmpl, context);
|
||||
}
|
||||
|
||||
static void ocf_mngt_cache_detach_stop_cache_io_finish(void *priv)
|
||||
{
|
||||
struct ocf_mngt_cache_unplug_context *context = priv;
|
||||
ocf_pipeline_next(context->pipeline);
|
||||
}
|
||||
|
||||
static void ocf_mngt_cache_detach_stop_cache_io(ocf_pipeline_t pipeline,
|
||||
void *priv, ocf_pipeline_arg_t arg)
|
||||
{
|
||||
struct ocf_mngt_cache_unplug_context *context = priv;
|
||||
ocf_cache_t cache = context->cache;
|
||||
struct env_refcnt *refcnt = &context->cache->refcnt.metadata;
|
||||
|
||||
ocf_refcnt_freeze(&cache->refcnt.metadata);
|
||||
ocf_refcnt_register_zero_cb(&cache->refcnt.metadata,
|
||||
ocf_mngt_cache_detach_stop_cache_io_finish, context);
|
||||
env_refcnt_freeze(refcnt);
|
||||
ocf_mngt_continue_pipeline_on_zero_refcnt(refcnt, context->pipeline);
|
||||
}
|
||||
|
||||
static void ocf_mngt_cache_detach_stop_cleaner_io_finish(void *priv)
|
||||
@@ -3840,7 +3902,7 @@ static void ocf_mngt_cache_detach_finish(ocf_pipeline_t pipeline,
|
||||
struct ocf_mngt_cache_unplug_context *context = priv;
|
||||
ocf_cache_t cache = context->cache;
|
||||
|
||||
ocf_refcnt_unfreeze(&cache->refcnt.dirty);
|
||||
env_refcnt_unfreeze(&cache->refcnt.dirty);
|
||||
|
||||
if (!error) {
|
||||
if (!context->cache_write_error) {
|
||||
@@ -3915,7 +3977,7 @@ void ocf_mngt_cache_detach(ocf_cache_t cache,
|
||||
context->cache = cache;
|
||||
|
||||
/* prevent dirty io */
|
||||
ocf_refcnt_freeze(&cache->refcnt.dirty);
|
||||
env_refcnt_freeze(&cache->refcnt.dirty);
|
||||
|
||||
ocf_pipeline_next(pipeline);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2021 Intel Corporation
|
||||
* Copyright(c) 2024 Huawei Technologies
|
||||
* Copyright(c) 2024-2025 Huawei Technologies
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "ocf/ocf.h"
|
||||
#include "ocf_env_refcnt.h"
|
||||
#include "ocf_mngt_common.h"
|
||||
#include "ocf_mngt_core_priv.h"
|
||||
#include "../ocf_priv.h"
|
||||
@@ -137,19 +138,11 @@ void cache_mngt_core_remove_from_cache(ocf_core_t core)
|
||||
if (!core->opened && --cache->ocf_core_inactive_count == 0)
|
||||
env_bit_clear(ocf_cache_state_incomplete, &cache->cache_state);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
env_refcnt_dec(&cache->refcnt.cache);
|
||||
}
|
||||
|
||||
void __set_cleaning_policy(ocf_cache_t cache,
|
||||
@@ -181,7 +174,7 @@ int ocf_mngt_cache_get_by_name(ocf_ctx_t ctx, const char *name, size_t name_len,
|
||||
|
||||
if (instance) {
|
||||
/* if cache is either fully initialized or during recovery */
|
||||
if (!ocf_refcnt_inc(&instance->refcnt.cache)) {
|
||||
if (!env_refcnt_inc(&instance->refcnt.cache)) {
|
||||
/* Cache not initialized yet */
|
||||
instance = NULL;
|
||||
}
|
||||
@@ -245,9 +238,15 @@ static void _ocf_mngt_cache_lock(ocf_cache_t cache,
|
||||
if (ocf_mngt_cache_get(cache))
|
||||
OCF_CMPL_RET(cache, priv, -OCF_ERR_CACHE_NOT_EXIST);
|
||||
|
||||
if (!env_refcnt_inc(&cache->refcnt.lock)) {
|
||||
ocf_mngt_cache_put(cache);
|
||||
OCF_CMPL_RET(cache, priv, -OCF_ERR_CACHE_NOT_EXIST);
|
||||
}
|
||||
|
||||
waiter = ocf_async_lock_new_waiter(&cache->lock,
|
||||
_ocf_mngt_cache_lock_complete);
|
||||
if (!waiter) {
|
||||
env_refcnt_dec(&cache->refcnt.lock);
|
||||
ocf_mngt_cache_put(cache);
|
||||
OCF_CMPL_RET(cache, priv, -OCF_ERR_NO_MEM);
|
||||
}
|
||||
@@ -259,20 +258,26 @@ static void _ocf_mngt_cache_lock(ocf_cache_t cache,
|
||||
context->priv = priv;
|
||||
|
||||
lock_fn(waiter);
|
||||
env_refcnt_dec(&cache->refcnt.lock);
|
||||
}
|
||||
|
||||
static int _ocf_mngt_cache_trylock(ocf_cache_t cache,
|
||||
ocf_trylock_fn_t trylock_fn, ocf_unlock_fn_t unlock_fn)
|
||||
{
|
||||
int result;
|
||||
int result = 0;
|
||||
|
||||
if (ocf_mngt_cache_get(cache))
|
||||
return -OCF_ERR_CACHE_NOT_EXIST;
|
||||
|
||||
if (!env_refcnt_inc(&cache->refcnt.lock)) {
|
||||
ocf_mngt_cache_put(cache);
|
||||
return -OCF_ERR_CACHE_NOT_EXIST;
|
||||
}
|
||||
|
||||
result = trylock_fn(&cache->lock);
|
||||
if (result) {
|
||||
ocf_mngt_cache_put(cache);
|
||||
return result;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (env_bit_test(ocf_cache_state_stopping, &cache->cache_state)) {
|
||||
@@ -281,6 +286,8 @@ static int _ocf_mngt_cache_trylock(ocf_cache_t cache,
|
||||
result = -OCF_ERR_CACHE_NOT_EXIST;
|
||||
}
|
||||
|
||||
out:
|
||||
env_refcnt_dec(&cache->refcnt.lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -293,13 +300,38 @@ static void _ocf_mngt_cache_unlock(ocf_cache_t cache,
|
||||
|
||||
int ocf_mngt_cache_lock_init(ocf_cache_t cache)
|
||||
{
|
||||
return ocf_async_lock_init(&cache->lock,
|
||||
int result;
|
||||
|
||||
result = env_refcnt_init(&cache->refcnt.lock, "lock", sizeof("lock"));
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
result = ocf_async_lock_init(&cache->lock,
|
||||
sizeof(struct ocf_mngt_cache_lock_context));
|
||||
if (result)
|
||||
env_refcnt_deinit(&cache->refcnt.lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void _ocf_mngt_cache_lock_deinit(void *priv)
|
||||
{
|
||||
ocf_cache_t cache = priv;
|
||||
|
||||
ocf_async_lock_deinit(&cache->lock);
|
||||
env_refcnt_dec(&cache->refcnt.cache);
|
||||
env_refcnt_deinit(&cache->refcnt.lock);
|
||||
}
|
||||
|
||||
void ocf_mngt_cache_lock_deinit(ocf_cache_t cache)
|
||||
{
|
||||
ocf_async_lock_deinit(&cache->lock);
|
||||
bool cache_get;
|
||||
|
||||
cache_get = env_refcnt_inc(&cache->refcnt.cache);
|
||||
ENV_BUG_ON(!cache_get);
|
||||
env_refcnt_freeze(&cache->refcnt.lock);
|
||||
env_refcnt_register_zero_cb(&cache->refcnt.lock,
|
||||
_ocf_mngt_cache_lock_deinit, cache);
|
||||
}
|
||||
|
||||
void ocf_mngt_cache_lock(ocf_cache_t cache,
|
||||
@@ -358,7 +390,7 @@ bool ocf_mngt_cache_is_locked(ocf_cache_t cache)
|
||||
/* if cache is either fully initialized or during recovery */
|
||||
static bool _ocf_mngt_cache_try_get(ocf_cache_t cache)
|
||||
{
|
||||
return !!ocf_refcnt_inc(&cache->refcnt.cache);
|
||||
return env_refcnt_inc(&cache->refcnt.cache);
|
||||
}
|
||||
|
||||
int ocf_mngt_cache_get(ocf_cache_t cache)
|
||||
@@ -483,3 +515,16 @@ int ocf_mngt_cache_visit_reverse(ocf_ctx_t ocf_ctx,
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void _ocf_mngt_continue_pipeline_on_zero_refcnt_cb(void *priv)
|
||||
{
|
||||
ocf_pipeline_next((ocf_pipeline_t)priv);
|
||||
}
|
||||
|
||||
void ocf_mngt_continue_pipeline_on_zero_refcnt(struct env_refcnt *refcnt,
|
||||
ocf_pipeline_t pipeline)
|
||||
{
|
||||
env_refcnt_register_zero_cb(refcnt,
|
||||
_ocf_mngt_continue_pipeline_on_zero_refcnt_cb,
|
||||
pipeline);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2021 Intel Corporation
|
||||
* Copyright(c) 2025 Huawei Technologies
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
@@ -7,6 +8,9 @@
|
||||
#ifndef __OCF_MNGT_COMMON_H__
|
||||
#define __OCF_MNGT_COMMON_H__
|
||||
|
||||
#include "ocf_env_refcnt.h"
|
||||
#include "../utils/utils_pipeline.h"
|
||||
|
||||
void cache_mngt_core_deinit(ocf_core_t core);
|
||||
|
||||
void cache_mngt_core_remove_from_meta(ocf_core_t core);
|
||||
@@ -33,4 +37,7 @@ bool ocf_mngt_cache_is_locked(ocf_cache_t cache);
|
||||
void __set_cleaning_policy(ocf_cache_t cache,
|
||||
ocf_cleaning_t new_cleaning_policy);
|
||||
|
||||
void ocf_mngt_continue_pipeline_on_zero_refcnt(struct env_refcnt *refcnt,
|
||||
ocf_pipeline_t pipeline);
|
||||
|
||||
#endif /* __OCF_MNGT_COMMON_H__ */
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "../metadata/metadata.h"
|
||||
#include "../engine/cache_engine.h"
|
||||
#include "../utils/utils_pipeline.h"
|
||||
#include "../utils/utils_cleaner.h"
|
||||
#include "../ocf_stats_priv.h"
|
||||
#include "../ocf_def_priv.h"
|
||||
#include "../cleaning/cleaning_ops.h"
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2022 Intel Corporation
|
||||
* Copyright(c) 2024 Huawei Technologies
|
||||
* Copyright(c) 2023-2025 Huawei Technologies Co., Ltd.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "ocf/ocf.h"
|
||||
#include "ocf_env_refcnt.h"
|
||||
#include "ocf_mngt_common.h"
|
||||
#include "../ocf_priv.h"
|
||||
#include "../metadata/metadata.h"
|
||||
@@ -15,7 +16,6 @@
|
||||
#include "../utils/utils_cache_line.h"
|
||||
#include "../utils/utils_user_part.h"
|
||||
#include "../utils/utils_pipeline.h"
|
||||
#include "../utils/utils_refcnt.h"
|
||||
#include "../ocf_request.h"
|
||||
#include "../ocf_def_priv.h"
|
||||
|
||||
@@ -82,12 +82,6 @@ struct ocf_mngt_cache_flush_context
|
||||
struct flush_containers_context fcs;
|
||||
};
|
||||
|
||||
static void _ocf_mngt_begin_flush_complete(void *priv)
|
||||
{
|
||||
struct ocf_mngt_cache_flush_context *context = priv;
|
||||
ocf_pipeline_next(context->pipeline);
|
||||
}
|
||||
|
||||
static void _ocf_mngt_begin_flush(ocf_pipeline_t pipeline, void *priv,
|
||||
ocf_pipeline_arg_t arg)
|
||||
{
|
||||
@@ -102,11 +96,11 @@ static void _ocf_mngt_begin_flush(ocf_pipeline_t pipeline, void *priv,
|
||||
OCF_PL_FINISH_RET(pipeline, -OCF_ERR_FLUSH_IN_PROGRESS);
|
||||
context->flags.lock = true;
|
||||
|
||||
ocf_refcnt_freeze(&cache->refcnt.dirty);
|
||||
env_refcnt_freeze(&cache->refcnt.dirty);
|
||||
context->flags.freeze = true;
|
||||
|
||||
ocf_refcnt_register_zero_cb(&cache->refcnt.dirty,
|
||||
_ocf_mngt_begin_flush_complete, context);
|
||||
ocf_mngt_continue_pipeline_on_zero_refcnt(&cache->refcnt.dirty,
|
||||
context->pipeline);
|
||||
}
|
||||
|
||||
bool ocf_mngt_core_is_dirty(ocf_core_t core)
|
||||
@@ -615,7 +609,7 @@ static void _ocf_mngt_flush_finish(ocf_pipeline_t pipeline, void *priv,
|
||||
ocf_core_t core = context->core;
|
||||
|
||||
if (context->flags.freeze)
|
||||
ocf_refcnt_unfreeze(&cache->refcnt.dirty);
|
||||
env_refcnt_unfreeze(&cache->refcnt.dirty);
|
||||
|
||||
if (context->flags.lock)
|
||||
env_mutex_unlock(&cache->flush_mutex);
|
||||
@@ -956,8 +950,8 @@ static void _ocf_mngt_deinit_clean_policy(ocf_pipeline_t pipeline, void *priv,
|
||||
|
||||
ocf_metadata_start_exclusive_access(&cache->metadata.lock);
|
||||
|
||||
ocf_refcnt_freeze(&cache->cleaner.refcnt);
|
||||
ocf_refcnt_register_zero_cb(&cache->cleaner.refcnt,
|
||||
env_refcnt_freeze(&cache->cleaner.refcnt);
|
||||
env_refcnt_register_zero_cb(&cache->cleaner.refcnt,
|
||||
_ocf_mngt_cleaning_deinit_complete, context);
|
||||
}
|
||||
|
||||
@@ -1011,7 +1005,7 @@ static void _ocf_mngt_set_cleaning_finish(ocf_pipeline_t pipeline, void *priv,
|
||||
struct ocf_mngt_cache_set_cleaning_context *context = priv;
|
||||
ocf_cache_t cache = context->cache;
|
||||
|
||||
ocf_refcnt_unfreeze(&cache->cleaner.refcnt);
|
||||
env_refcnt_unfreeze(&cache->cleaner.refcnt);
|
||||
ocf_metadata_end_exclusive_access(&cache->metadata.lock);
|
||||
|
||||
context->cmpl(context->priv, error);
|
||||
|
||||
Reference in New Issue
Block a user