From 52824adaaf57904d0f2dfcc88a65bd34f0b8e192 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Thu, 14 Oct 2021 18:41:30 +0200 Subject: [PATCH] Additional cleaning policy info outside of the SB Starting cache in a standby mode requires access to a valid cleaning policy type. If the policy is stored only in the superblock, it may be overridden by one of the metadata passive updates. To prevent losing the information it should be stored in cache's runtime metadata. Signed-off-by: Michal Mielewczyk --- src/cleaning/cleaning.h | 1 + src/cleaning/cleaning_ops.h | 16 ++++++++-------- src/mngt/ocf_mngt_cache.c | 29 +++++++++++++++-------------- src/mngt/ocf_mngt_common.c | 7 +++++++ src/mngt/ocf_mngt_common.h | 3 +++ src/mngt/ocf_mngt_flush.c | 6 +++--- src/ocf_cache.c | 2 +- src/ocf_io_class.c | 2 +- 8 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/cleaning/cleaning.h b/src/cleaning/cleaning.h index 5eee0b8..c48d50e 100644 --- a/src/cleaning/cleaning.h +++ b/src/cleaning/cleaning.h @@ -41,6 +41,7 @@ struct cleaning_policy_meta { struct ocf_cleaner { struct ocf_refcnt refcnt __attribute__((aligned(64))); + ocf_cleaning_t policy; void *cleaning_policy_context; ocf_queue_t io_queue; ocf_cleaner_end_t end; diff --git a/src/cleaning/cleaning_ops.h b/src/cleaning/cleaning_ops.h index 3f72f02..a0f6177 100644 --- a/src/cleaning/cleaning_ops.h +++ b/src/cleaning/cleaning_ops.h @@ -91,7 +91,7 @@ static inline void ocf_cleaning_deinitialize(ocf_cache_t cache) { ocf_cleaning_t policy; - policy = cache->conf_meta->cleaning_policy_type; + policy = cache->cleaner.policy; ENV_BUG_ON(policy >= ocf_cleaning_max); @@ -110,7 +110,7 @@ static inline int ocf_cleaning_add_core(ocf_cache_t cache, if (unlikely(!ocf_refcnt_inc(&cache->cleaner.refcnt))) return -OCF_ERR_NO_LOCK; - policy = cache->conf_meta->cleaning_policy_type; + policy = cache->cleaner.policy; ENV_BUG_ON(policy >= ocf_cleaning_max); @@ -133,7 +133,7 @@ static inline void ocf_cleaning_remove_core(ocf_cache_t cache, if (unlikely(!ocf_refcnt_inc(&cache->cleaner.refcnt))) return; - policy = cache->conf_meta->cleaning_policy_type; + policy = cache->cleaner.policy; ENV_BUG_ON(policy >= ocf_cleaning_max); @@ -154,7 +154,7 @@ static inline void ocf_cleaning_init_cache_block(ocf_cache_t cache, if (unlikely(!ocf_refcnt_inc(&cache->cleaner.refcnt))) return; - policy = cache->conf_meta->cleaning_policy_type; + policy = cache->cleaner.policy; ENV_BUG_ON(policy >= ocf_cleaning_max); if (unlikely(!cleaning_policy_ops[policy].init_cache_block)) @@ -174,7 +174,7 @@ static inline void ocf_cleaning_purge_cache_block(ocf_cache_t cache, if (unlikely(!ocf_refcnt_inc(&cache->cleaner.refcnt))) return; - policy = cache->conf_meta->cleaning_policy_type; + policy = cache->cleaner.policy; ENV_BUG_ON(policy >= ocf_cleaning_max); if (unlikely(!cleaning_policy_ops[policy].purge_cache_block)) @@ -194,7 +194,7 @@ static inline void ocf_cleaning_purge_range(ocf_cache_t cache, if (unlikely(!ocf_refcnt_inc(&cache->cleaner.refcnt))) return; - policy = cache->conf_meta->cleaning_policy_type; + policy = cache->cleaner.policy; ENV_BUG_ON(policy >= ocf_cleaning_max); if (unlikely(!cleaning_policy_ops[policy].purge_range)) @@ -215,7 +215,7 @@ static inline void ocf_cleaning_set_hot_cache_line(ocf_cache_t cache, if (unlikely(!ocf_refcnt_inc(&cache->cleaner.refcnt))) return; - policy = cache->conf_meta->cleaning_policy_type; + policy = cache->cleaner.policy; ENV_BUG_ON(policy >= ocf_cleaning_max); if (unlikely(!cleaning_policy_ops[policy].set_hot_cache_line)) @@ -259,7 +259,7 @@ static inline void ocf_cleaning_perform_cleaning(ocf_cache_t cache, if (unlikely(!ocf_refcnt_inc(&cache->cleaner.refcnt))) return; - policy = cache->conf_meta->cleaning_policy_type; + policy = cache->cleaner.policy; ENV_BUG_ON(policy >= ocf_cleaning_max); if (unlikely(!cleaning_policy_ops[policy].perform_cleaning)) diff --git a/src/mngt/ocf_mngt_cache.c b/src/mngt/ocf_mngt_cache.c index f3de681..8581e67 100644 --- a/src/mngt/ocf_mngt_cache.c +++ b/src/mngt/ocf_mngt_cache.c @@ -227,7 +227,6 @@ static void __populate_free_safe(ocf_cache_t cache) static ocf_error_t __init_cleaning_policy(ocf_cache_t cache) { - ocf_cleaning_t cleaning_policy = ocf_cleaning_default; int i; OCF_ASSERT_PLUGGED(cache); @@ -237,9 +236,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); - cache->conf_meta->cleaning_policy_type = ocf_cleaning_default; - - return ocf_cleaning_initialize(cache, cleaning_policy, 1); + return ocf_cleaning_initialize(cache, cache->cleaner.policy, 1); } static void __deinit_cleaning_policy(ocf_cache_t cache) @@ -541,12 +538,7 @@ static void _ocf_mngt_recovery_rebuild_metadata(ocf_cache_t cache) static void _ocf_mngt_bind_rebuild_metadata(ocf_cache_t cache) { - ocf_cleaning_t clean_policy = cache->conf_meta->cleaning_policy_type; - cache->conf_meta->cleaning_policy_type = ocf_cleaning_nop; - _ocf_mngt_rebuild_metadata(cache, true); - - cache->conf_meta->cleaning_policy_type = clean_policy; } static inline ocf_error_t _ocf_init_cleaning_policy(ocf_cache_t cache, @@ -578,8 +570,7 @@ static void _ocf_mngt_load_post_metadata_load(ocf_pipeline_t pipeline, __populate_free_safe(cache); } - result = _ocf_init_cleaning_policy(cache, - cache->conf_meta->cleaning_policy_type, + result = _ocf_init_cleaning_policy(cache, cache->cleaner.policy, context->metadata.shutdown_status); if (result) @@ -1222,6 +1213,7 @@ static void _ocf_mngt_cache_init(ocf_cache_t cache, cache->conf_meta->cache_mode = params->metadata.cache_mode; cache->conf_meta->metadata_layout = params->metadata.layout; cache->conf_meta->promotion_policy_type = params->metadata.promotion_policy; + __set_cleaning_policy(cache, ocf_cleaning_default); INIT_LIST_HEAD(&cache->io_queues); @@ -1410,6 +1402,7 @@ static void _ocf_mngt_load_superblock_complete(void *priv, int error) { struct ocf_cache_attach_context *context = priv; ocf_cache_t cache = context->cache; + ocf_cleaning_t loaded_clean_policy = cache->conf_meta->cleaning_policy_type; if (cache->conf_meta->cachelines != ocf_metadata_get_cachelines_count(cache)) { @@ -1419,6 +1412,15 @@ static void _ocf_mngt_load_superblock_complete(void *priv, int error) -OCF_ERR_START_CACHE_FAIL); } + if (loaded_clean_policy >= ocf_cleaning_max) { + ocf_cache_log(cache, log_err, + "ERROR: Invalid cleaning policy!\n"); + OCF_PL_FINISH_RET(context->pipeline, + -OCF_ERR_START_CACHE_FAIL); + } + + __set_cleaning_policy(cache, loaded_clean_policy); + if (error) { ocf_cache_log(cache, log_err, "ERROR: Cannot load cache state\n"); @@ -2080,8 +2082,7 @@ static void _ocf_mngt_bind_init_cleaning(ocf_pipeline_t pipeline, ocf_cache_t cache = context->cache; ocf_error_t result; - result = _ocf_init_cleaning_policy(cache, - cache->conf_meta->cleaning_policy_type, + result = _ocf_init_cleaning_policy(cache, cache->cleaner.policy, context->metadata.shutdown_status); if (result) @@ -2821,7 +2822,7 @@ static int _ocf_mngt_cache_load_core_log(ocf_core_t core, void *cntx) static void _ocf_mngt_cache_load_log(ocf_cache_t cache) { ocf_cache_mode_t cache_mode = ocf_cache_get_mode(cache); - ocf_cleaning_t cleaning_type = cache->conf_meta->cleaning_policy_type; + ocf_cleaning_t cleaning_type = cache->cleaner.policy; ocf_promotion_t promotion_type = cache->conf_meta->promotion_policy_type; ocf_cache_log(cache, log_info, "Successfully loaded\n"); diff --git a/src/mngt/ocf_mngt_common.c b/src/mngt/ocf_mngt_common.c index 6d39a3b..3668e65 100644 --- a/src/mngt/ocf_mngt_common.c +++ b/src/mngt/ocf_mngt_common.c @@ -151,6 +151,13 @@ void ocf_mngt_cache_put(ocf_cache_t cache) } } +void __set_cleaning_policy(ocf_cache_t cache, + ocf_cleaning_t new_cleaning_policy) +{ + cache->conf_meta->cleaning_policy_type = new_cleaning_policy; + cache->cleaner.policy = new_cleaning_policy; +} + int ocf_mngt_cache_get_by_name(ocf_ctx_t ctx, const char *name, size_t name_len, ocf_cache_t *cache) { diff --git a/src/mngt/ocf_mngt_common.h b/src/mngt/ocf_mngt_common.h index 5e8b301..751a2e0 100644 --- a/src/mngt/ocf_mngt_common.h +++ b/src/mngt/ocf_mngt_common.h @@ -30,4 +30,7 @@ void ocf_mngt_cache_lock_deinit(ocf_cache_t cache); bool ocf_mngt_cache_is_locked(ocf_cache_t cache); +void __set_cleaning_policy(ocf_cache_t cache, + ocf_cleaning_t new_cleaning_policy); + #endif /* __OCF_MNGT_COMMON_H__ */ diff --git a/src/mngt/ocf_mngt_flush.c b/src/mngt/ocf_mngt_flush.c index 4e5ec6a..440db41 100644 --- a/src/mngt/ocf_mngt_flush.c +++ b/src/mngt/ocf_mngt_flush.c @@ -968,7 +968,7 @@ static void _ocf_mngt_init_clean_policy(ocf_pipeline_t pipeline, void *priv, ocf_cleaning_get_name(new_policy)); } - cache->conf_meta->cleaning_policy_type = new_policy; + __set_cleaning_policy(cache, new_policy); ocf_refcnt_unfreeze(&cache->cleaner.refcnt); ocf_metadata_end_exclusive_access(&cache->metadata.lock); @@ -1014,7 +1014,7 @@ void ocf_mngt_cache_cleaning_set_policy(ocf_cache_t cache, if (ocf_cache_is_standby(cache)) OCF_CMPL_RET(priv, -OCF_ERR_CACHE_STANDBY); - old_policy = cache->conf_meta->cleaning_policy_type; + old_policy = cache->cleaner.policy; if (new_policy == old_policy) { ocf_cache_log(cache, log_info, "Cleaning policy %s is already " @@ -1047,7 +1047,7 @@ int ocf_mngt_cache_cleaning_get_policy(ocf_cache_t cache, ocf_cleaning_t *type) if (ocf_cache_is_standby(cache)) return -OCF_ERR_CACHE_STANDBY; - *type = cache->conf_meta->cleaning_policy_type; + *type = cache->cleaner.policy; return 0; } diff --git a/src/ocf_cache.c b/src/ocf_cache.c index f0fe2bb..2522f61 100644 --- a/src/ocf_cache.c +++ b/src/ocf_cache.c @@ -196,7 +196,7 @@ int ocf_cache_get_info(ocf_cache_t cache, struct ocf_cache_info *info) info->fallback_pt.error_counter = env_atomic_read(&cache->fallback_pt_error_counter); - info->cleaning_policy = cache->conf_meta->cleaning_policy_type; + info->cleaning_policy = cache->cleaner.policy; info->promotion_policy = cache->conf_meta->promotion_policy_type; info->cache_line_size = ocf_line_size(cache); diff --git a/src/ocf_io_class.c b/src/ocf_io_class.c index 3a3554a..b856e90 100644 --- a/src/ocf_io_class.c +++ b/src/ocf_io_class.c @@ -42,7 +42,7 @@ int ocf_cache_io_class_get_info(ocf_cache_t cache, uint32_t io_class, info->min_size = cache->user_parts[part_id].config->min_size; info->max_size = cache->user_parts[part_id].config->max_size; - info->cleaning_policy_type = cache->conf_meta->cleaning_policy_type; + info->cleaning_policy_type = cache->cleaner.policy; info->cache_mode = cache->user_parts[part_id].config->cache_mode;