diff --git a/src/cleaning/acp.c b/src/cleaning/acp.c index efde479..841bf47 100644 --- a/src/cleaning/acp.c +++ b/src/cleaning/acp.c @@ -235,32 +235,6 @@ void cleaning_policy_acp_deinitialize(struct ocf_cache *cache) cache->cleaner.cleaning_policy_context = NULL; } -static void _acp_rebuild(struct ocf_cache *cache) -{ - ocf_cache_line_t cline; - ocf_core_id_t cline_core_id; - uint32_t step = 0; - - for (cline = 0; cline < cache->device->collision_table_entries; cline++) { - ocf_metadata_get_core_and_part_id(cache, cline, &cline_core_id, - NULL); - - OCF_COND_RESCHED_DEFAULT(step); - - if (cline_core_id == OCF_CORE_MAX) - continue; - - cleaning_policy_acp_init_cache_block(cache, cline); - - if (!metadata_test_dirty(cache, cline)) - continue; - - cleaning_policy_acp_set_hot_cache_line(cache, cline); - } - - ocf_cache_log(cache, log_info, "Finished rebuilding ACP metadata\n"); -} - void cleaning_policy_acp_setup(struct ocf_cache *cache) { struct acp_cleaning_policy_config *config; @@ -271,7 +245,7 @@ void cleaning_policy_acp_setup(struct ocf_cache *cache) config->flush_max_buffers = OCF_ACP_DEFAULT_FLUSH_MAX_BUFFERS; } -int cleaning_policy_acp_init_common(ocf_cache_t cache) +int cleaning_policy_acp_initialize(ocf_cache_t cache, int kick_cleaner) { struct acp_context *acp; int err, i; @@ -317,19 +291,8 @@ int cleaning_policy_acp_init_common(ocf_cache_t cache) } } - return 0; -} - -int cleaning_policy_acp_initialize(ocf_cache_t cache, int init_metadata) -{ - int result; - - result = cleaning_policy_acp_init_common(cache); - if (result) - return result; - - _acp_rebuild(cache); - ocf_kick_cleaner(cache); + if (kick_cleaner) + ocf_kick_cleaner(cache); return 0; } @@ -498,10 +461,6 @@ void cleaning_policy_acp_populate(ocf_cache_t cache, } } - result = cleaning_policy_acp_init_common(cache); - if (result) - goto err; - ocf_parallelize_run(parallelize); return; diff --git a/src/cleaning/acp.h b/src/cleaning/acp.h index 62fb11e..d260501 100644 --- a/src/cleaning/acp.h +++ b/src/cleaning/acp.h @@ -10,7 +10,7 @@ void cleaning_policy_acp_setup(ocf_cache_t cache); -int cleaning_policy_acp_initialize(ocf_cache_t cache, int init_metadata); +int cleaning_policy_acp_initialize(ocf_cache_t cache, int kick_cleaner); void cleaning_policy_acp_populate(ocf_cache_t cache, ocf_cleaning_populate_end_t cmpl, void *priv); diff --git a/src/cleaning/alru.c b/src/cleaning/alru.c index 9536b7e..d3065c5 100644 --- a/src/cleaning/alru.c +++ b/src/cleaning/alru.c @@ -349,42 +349,6 @@ void cleaning_policy_alru_set_hot_cache_line(struct ocf_cache *cache, env_spinlock_unlock(&ctx->list_lock[part_id]); } -static void _alru_rebuild(struct ocf_cache *cache) -{ - struct ocf_user_part *user_part; - struct alru_cleaning_policy *part_alru; - ocf_part_id_t part_id; - ocf_core_id_t core_id; - ocf_cache_line_t cline; - uint32_t step = 0; - - for_each_user_part(cache, user_part, part_id) { - /* ALRU initialization */ - part_alru = &user_part->clean_pol->policy.alru; - env_atomic_set(&part_alru->size, 0); - part_alru->lru_head = cache->device->collision_table_entries; - part_alru->lru_tail = cache->device->collision_table_entries; - cache->device->runtime_meta->cleaning_thread_access = 0; - } - - for (cline = 0; cline < cache->device->collision_table_entries; cline++) { - ocf_metadata_get_core_and_part_id(cache, cline, &core_id, - NULL); - - OCF_COND_RESCHED_DEFAULT(step); - - if (core_id == OCF_CORE_MAX) - continue; - - cleaning_policy_alru_init_cache_block(cache, cline); - - if (!metadata_test_dirty(cache, cline)) - continue; - - cleaning_policy_alru_set_hot_cache_line(cache, cline); - } -} - void cleaning_policy_alru_setup(struct ocf_cache *cache) { struct alru_cleaning_policy_config *config; @@ -397,7 +361,7 @@ void cleaning_policy_alru_setup(struct ocf_cache *cache) config->activity_threshold = OCF_ALRU_DEFAULT_ACTIVITY_THRESHOLD; } -int cleaning_policy_alru_init_common(ocf_cache_t cache) +int cleaning_policy_alru_initialize(ocf_cache_t cache, int kick_cleaner) { struct alru_context *ctx; int error = 0; @@ -426,21 +390,8 @@ int cleaning_policy_alru_init_common(ocf_cache_t cache) cache->cleaner.cleaning_policy_context = ctx; - return 0; -} - -int cleaning_policy_alru_initialize(ocf_cache_t cache, int init_metadata) -{ - int result; - - result = cleaning_policy_alru_init_common(cache); - if (result) - return result; - - if (init_metadata) - _alru_rebuild(cache); - - ocf_kick_cleaner(cache); + if (kick_cleaner) + ocf_kick_cleaner(cache); return 0; } @@ -598,14 +549,6 @@ void cleaning_policy_alru_populate(ocf_cache_t cache, return; } - - result = cleaning_policy_alru_init_common(cache); - if (result) { - ocf_parallelize_destroy(parallelize); - cmpl(priv, result); - return; - } - for_each_user_part(cache, user_part, part_id) { /* ALRU initialization */ part_alru = &user_part->clean_pol->policy.alru; diff --git a/src/cleaning/alru.h b/src/cleaning/alru.h index 49adf9e..8d8c6b5 100644 --- a/src/cleaning/alru.h +++ b/src/cleaning/alru.h @@ -10,7 +10,7 @@ #include "alru_structs.h" void cleaning_policy_alru_setup(ocf_cache_t cache); -int cleaning_policy_alru_initialize(ocf_cache_t cache, int init_metadata); +int cleaning_policy_alru_initialize(ocf_cache_t cache, int kick_cleaner); void cleaning_policy_alru_populate(ocf_cache_t cache, ocf_cleaning_populate_end_t cmpl, void *priv); void cleaning_policy_alru_deinitialize(ocf_cache_t cache); diff --git a/src/cleaning/cleaning_ops.h b/src/cleaning/cleaning_ops.h index 6ba7bcf..60493a8 100644 --- a/src/cleaning/cleaning_ops.h +++ b/src/cleaning/cleaning_ops.h @@ -81,14 +81,14 @@ static inline void ocf_cleaning_setup(ocf_cache_t cache, ocf_cleaning_t policy) } static inline int ocf_cleaning_initialize(ocf_cache_t cache, - ocf_cleaning_t policy, int init_metadata) + ocf_cleaning_t policy, int kick_cleaner) { ENV_BUG_ON(policy >= ocf_cleaning_max); if (unlikely(!cleaning_policy_ops[policy].initialize)) return 0; - return cleaning_policy_ops[policy].initialize(cache, init_metadata); + return cleaning_policy_ops[policy].initialize(cache, kick_cleaner); } static inline void ocf_cleaning_populate(ocf_cache_t cache, diff --git a/src/mngt/ocf_mngt_cache.c b/src/mngt/ocf_mngt_cache.c index 2e8afd1..b249fdb 100644 --- a/src/mngt/ocf_mngt_cache.c +++ b/src/mngt/ocf_mngt_cache.c @@ -229,7 +229,7 @@ static ocf_error_t __init_cleaning_policy(ocf_cache_t cache) for (i = 0; i < ocf_cleaning_max; i++) ocf_cleaning_setup(cache, i); - return ocf_cleaning_initialize(cache, cache->cleaner.policy, 1); + return ocf_cleaning_initialize(cache, cache->cleaner.policy, false); } static void __deinit_cleaning_policy(ocf_cache_t cache) @@ -724,13 +724,19 @@ static void _ocf_mngt_load_init_cleaning(ocf_pipeline_t pipeline, ocf_error_t result; if (context->metadata.shutdown_status == ocf_metadata_clean_shutdown) { - result = ocf_cleaning_initialize(cache, - cache->cleaner.policy, 0); + /* Cleaning policy structures have been loaded so no need to populate + them for the second time */ + result = ocf_cleaning_initialize(cache, cache->cleaner.policy, true); OCF_PL_NEXT_ON_SUCCESS_RET(pipeline, result); - } - ocf_cleaning_populate(cache, cache->cleaner.policy, - _ocf_mngt_cleaning_populate_complete, context); + } else { + result = ocf_cleaning_initialize(cache, cache->cleaner.policy, false); + if (result) + OCF_PL_FINISH_RET(pipeline, result); + + ocf_cleaning_populate(cache, cache->cleaner.policy, + _ocf_mngt_cleaning_populate_complete, context); + } } static void _ocf_mngt_init_metadata_complete(void *priv, int error) @@ -1324,6 +1330,24 @@ static void _ocf_mngt_attach_populate_free(ocf_pipeline_t pipeline, context); } +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) + 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 + */ + cache->conf_meta->dirty_flushed = true; + + context->flags.cleaning_initialized = true; + + OCF_PL_NEXT_RET(context->pipeline); +} + static void _ocf_mngt_attach_init_services(ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { @@ -1343,13 +1367,8 @@ static void _ocf_mngt_attach_init_services(ocf_pipeline_t pipeline, OCF_PL_FINISH_RET(pipeline, result); } - /* In initial cache state there is no dirty data, so all dirty data is - considered to be flushed - */ - cache->conf_meta->dirty_flushed = true; - context->flags.cleaning_initialized = true; - - ocf_pipeline_next(pipeline); + ocf_cleaning_populate(cache, cache->cleaner.policy, + _ocf_mngt_cleaning_populate_init_complete, context); } uint64_t _ocf_mngt_calculate_ram_needed(ocf_cache_line_size_t line_size, diff --git a/src/mngt/ocf_mngt_flush.c b/src/mngt/ocf_mngt_flush.c index 5702ffc..aa894bb 100644 --- a/src/mngt/ocf_mngt_flush.c +++ b/src/mngt/ocf_mngt_flush.c @@ -961,18 +961,16 @@ static void _ocf_mngt_deinit_clean_policy(ocf_pipeline_t pipeline, void *priv, _ocf_mngt_cleaning_deinit_complete, context); } -static void _ocf_mngt_init_clean_policy(ocf_pipeline_t pipeline, void *priv, - ocf_pipeline_arg_t arg) +static void _ocf_mngt_cleaning_init_complete(void *priv, int error) { - int result; struct ocf_mngt_cache_set_cleaning_context *context = priv; + ocf_pipeline_t pipeline = context->pipeline; ocf_cache_t cache = context->cache; ocf_cleaning_t old_policy = context->old_policy; ocf_cleaning_t new_policy = context->new_policy; ocf_cleaning_t emergency_policy = ocf_cleaning_nop; - result = ocf_cleaning_initialize(cache, new_policy, 1); - if (result) { + if (error) { ocf_cache_log(cache, log_info, "Failed to initialize %s cleaning " "policy. Setting %s instead\n", ocf_cleaning_get_name(new_policy), @@ -986,16 +984,35 @@ static void _ocf_mngt_init_clean_policy(ocf_pipeline_t pipeline, void *priv, __set_cleaning_policy(cache, new_policy); - ocf_refcnt_unfreeze(&cache->cleaner.refcnt); - ocf_metadata_end_exclusive_access(&cache->metadata.lock); + OCF_PL_NEXT_ON_SUCCESS_RET(pipeline, error); - OCF_PL_NEXT_ON_SUCCESS_RET(pipeline, result); +} + +static void _ocf_mngt_init_clean_policy(ocf_pipeline_t pipeline, void *priv, + ocf_pipeline_arg_t arg) +{ + int result; + struct ocf_mngt_cache_set_cleaning_context *context = priv; + ocf_cache_t cache = context->cache; + ocf_cleaning_t new_policy = context->new_policy; + + result = ocf_cleaning_initialize(cache, new_policy, false); + if (result) { + _ocf_mngt_cleaning_init_complete(context, result); + } else { + ocf_cleaning_populate(cache, new_policy, + _ocf_mngt_cleaning_init_complete, context); + } } static void _ocf_mngt_set_cleaning_finish(ocf_pipeline_t pipeline, void *priv, int error) { struct ocf_mngt_cache_set_cleaning_context *context = priv; + ocf_cache_t cache = context->cache; + + ocf_refcnt_unfreeze(&cache->cleaner.refcnt); + ocf_metadata_end_exclusive_access(&cache->metadata.lock); context->cmpl(context->priv, error);