Cleaner context ref counter

To prevent deinitializing cleaner context (i.e. during switching policy) during
processing requests, access to cleaner should be protected with reference
counter

Signed-off-by: Michal Mielewczyk <michal.mielewczyk@intel.com>
This commit is contained in:
Michal Mielewczyk 2021-07-20 10:49:30 +02:00
parent f33a6e5ce0
commit b83da68f85
4 changed files with 65 additions and 4 deletions

View File

@ -10,6 +10,7 @@
#include "nop_structs.h"
#include "acp_structs.h"
#include "ocf/ocf_cleaner.h"
#include "../utils/utils_refcnt.h"
#define CLEANING_POLICY_CONFIG_BYTES 256
#define CLEANING_POLICY_TYPE_MAX 4
@ -39,6 +40,7 @@ struct cleaning_policy_meta {
};
struct ocf_cleaner {
struct ocf_refcnt refcnt __attribute__((aligned(64)));
void *cleaning_policy_context;
ocf_queue_t io_queue;
ocf_cleaner_end_t end;

View File

@ -9,6 +9,7 @@
#include "../metadata/metadata_superblock.h"
#include "../metadata/metadata_structs.h"
#include "../ocf_cache_priv.h"
#include "../utils/utils_refcnt.h"
struct cleaning_policy_ops {
void (*setup)(ocf_cache_t cache);
@ -104,6 +105,10 @@ static inline int ocf_cleaning_add_core(ocf_cache_t cache,
ocf_core_id_t core_id)
{
ocf_cleaning_t policy;
int result = 0;
if (unlikely(!ocf_refcnt_inc(&cache->cleaner.refcnt)))
return -OCF_ERR_NO_LOCK;
policy = cache->conf_meta->cleaning_policy_type;
@ -112,7 +117,12 @@ static inline int ocf_cleaning_add_core(ocf_cache_t cache,
if (unlikely(!cleaning_policy_ops[policy].add_core))
goto unlock;
return cleaning_policy_ops[policy].add_core(cache, core_id);
result = cleaning_policy_ops[policy].add_core(cache, core_id);
unlock:
ocf_refcnt_dec(&cache->cleaner.refcnt);
return result;
}
static inline void ocf_cleaning_remove_core(ocf_cache_t cache,
@ -120,6 +130,9 @@ static inline void ocf_cleaning_remove_core(ocf_cache_t cache,
{
ocf_cleaning_t policy;
if (unlikely(!ocf_refcnt_inc(&cache->cleaner.refcnt)))
return;
policy = cache->conf_meta->cleaning_policy_type;
ENV_BUG_ON(policy >= ocf_cleaning_max);
@ -128,6 +141,9 @@ static inline void ocf_cleaning_remove_core(ocf_cache_t cache,
goto unlock;
cleaning_policy_ops[policy].remove_core(cache, core_id);
unlock:
ocf_refcnt_dec(&cache->cleaner.refcnt);
}
static inline void ocf_cleaning_init_cache_block(ocf_cache_t cache,
@ -135,6 +151,9 @@ static inline void ocf_cleaning_init_cache_block(ocf_cache_t cache,
{
ocf_cleaning_t policy;
if (unlikely(!ocf_refcnt_inc(&cache->cleaner.refcnt)))
return;
policy = cache->conf_meta->cleaning_policy_type;
ENV_BUG_ON(policy >= ocf_cleaning_max);
@ -142,6 +161,9 @@ static inline void ocf_cleaning_init_cache_block(ocf_cache_t cache,
goto unlock;
cleaning_policy_ops[policy].init_cache_block(cache, cache_line);
unlock:
ocf_refcnt_dec(&cache->cleaner.refcnt);
}
static inline void ocf_cleaning_purge_cache_block(ocf_cache_t cache,
@ -149,6 +171,9 @@ static inline void ocf_cleaning_purge_cache_block(ocf_cache_t cache,
{
ocf_cleaning_t policy;
if (unlikely(!ocf_refcnt_inc(&cache->cleaner.refcnt)))
return;
policy = cache->conf_meta->cleaning_policy_type;
ENV_BUG_ON(policy >= ocf_cleaning_max);
@ -156,6 +181,9 @@ static inline void ocf_cleaning_purge_cache_block(ocf_cache_t cache,
goto unlock;
cleaning_policy_ops[policy].purge_cache_block(cache, cache_line);
unlock:
ocf_refcnt_dec(&cache->cleaner.refcnt);
}
static inline void ocf_cleaning_purge_range(ocf_cache_t cache,
@ -163,6 +191,9 @@ static inline void ocf_cleaning_purge_range(ocf_cache_t cache,
{
ocf_cleaning_t policy;
if (unlikely(!ocf_refcnt_inc(&cache->cleaner.refcnt)))
return;
policy = cache->conf_meta->cleaning_policy_type;
ENV_BUG_ON(policy >= ocf_cleaning_max);
@ -171,6 +202,9 @@ static inline void ocf_cleaning_purge_range(ocf_cache_t cache,
cleaning_policy_ops[policy].purge_range(cache, core_id, start_byte,
end_byte);
unlock:
ocf_refcnt_dec(&cache->cleaner.refcnt);
}
static inline void ocf_cleaning_set_hot_cache_line(ocf_cache_t cache,
@ -178,6 +212,9 @@ static inline void ocf_cleaning_set_hot_cache_line(ocf_cache_t cache,
{
ocf_cleaning_t policy;
if (unlikely(!ocf_refcnt_inc(&cache->cleaner.refcnt)))
return;
policy = cache->conf_meta->cleaning_policy_type;
ENV_BUG_ON(policy >= ocf_cleaning_max);
@ -185,6 +222,9 @@ static inline void ocf_cleaning_set_hot_cache_line(ocf_cache_t cache,
goto unlock;
cleaning_policy_ops[policy].set_hot_cache_line(cache, cache_line);
unlock:
ocf_refcnt_dec(&cache->cleaner.refcnt);
}
static inline int ocf_cleaning_set_param(ocf_cache_t cache,
@ -216,6 +256,9 @@ static inline void ocf_cleaning_perform_cleaning(ocf_cache_t cache,
{
ocf_cleaning_t policy;
if (unlikely(!ocf_refcnt_inc(&cache->cleaner.refcnt)))
return;
policy = cache->conf_meta->cleaning_policy_type;
ENV_BUG_ON(policy >= ocf_cleaning_max);
@ -223,6 +266,9 @@ static inline void ocf_cleaning_perform_cleaning(ocf_cache_t cache,
goto unlock;
cleaning_policy_ops[policy].perform_cleaning(cache, cmpl);
unlock:
ocf_refcnt_dec(&cache->cleaner.refcnt);
}
static inline const char *ocf_cleaning_get_name(ocf_cleaning_t policy)

View File

@ -205,6 +205,8 @@ static ocf_error_t __init_cleaning_policy(ocf_cache_t cache)
OCF_ASSERT_PLUGGED(cache);
ocf_refcnt_init(&cache->cleaner.refcnt);
for (i = 0; i < ocf_cleaning_max; i++)
ocf_cleaning_setup(cache, i);

View File

@ -917,6 +917,16 @@ struct ocf_mngt_cache_set_cleaning_context
void *priv;
};
static void _ocf_mngt_cleaning_deinit_complete(void *priv)
{
struct ocf_mngt_cache_set_cleaning_context *context = priv;
ocf_cache_t cache = context->cache;
ocf_cleaning_deinitialize(cache);
ocf_pipeline_next(context->pipeline);
}
static void _ocf_mngt_deinit_clean_policy(ocf_pipeline_t pipeline, void *priv,
ocf_pipeline_arg_t arg)
{
@ -925,9 +935,9 @@ static void _ocf_mngt_deinit_clean_policy(ocf_pipeline_t pipeline, void *priv,
ocf_metadata_start_exclusive_access(&cache->metadata.lock);
ocf_cleaning_deinitialize(cache);
ocf_pipeline_next(context->pipeline);
ocf_refcnt_freeze(&cache->cleaner.refcnt);
ocf_refcnt_register_zero_cb(&cache->cleaner.refcnt,
_ocf_mngt_cleaning_deinit_complete, context);
}
static void _ocf_mngt_init_clean_policy(ocf_pipeline_t pipeline, void *priv,
@ -955,6 +965,7 @@ static void _ocf_mngt_init_clean_policy(ocf_pipeline_t pipeline, void *priv,
cache->conf_meta->cleaning_policy_type = new_policy;
ocf_refcnt_unfreeze(&cache->cleaner.refcnt);
ocf_metadata_end_exclusive_access(&cache->metadata.lock);
OCF_PL_NEXT_ON_SUCCESS_RET(pipeline, result);