138 lines
3.5 KiB
C
138 lines
3.5 KiB
C
/*
|
|
* Copyright(c) 2012-2018 Intel Corporation
|
|
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
|
*/
|
|
|
|
#include "cleaning.h"
|
|
#include "alru.h"
|
|
#include "acp.h"
|
|
#include "../ocf_priv.h"
|
|
#include "../ocf_cache_priv.h"
|
|
#include "../ocf_ctx_priv.h"
|
|
#include "../mngt/ocf_mngt_common.h"
|
|
#include "../metadata/metadata.h"
|
|
|
|
#define SLEEP_TIME_MS (1000)
|
|
|
|
struct cleaning_policy_ops cleaning_policy_ops[ocf_cleaning_max] = {
|
|
[ocf_cleaning_nop] = {
|
|
.name = "nop",
|
|
},
|
|
[ocf_cleaning_alru] = {
|
|
.setup = cleaning_policy_alru_setup,
|
|
.init_cache_block = cleaning_policy_alru_init_cache_block,
|
|
.purge_cache_block = cleaning_policy_alru_purge_cache_block,
|
|
.purge_range = cleaning_policy_alru_purge_range,
|
|
.set_hot_cache_line = cleaning_policy_alru_set_hot_cache_line,
|
|
.initialize = cleaning_policy_alru_initialize,
|
|
.set_cleaning_param = cleaning_policy_alru_set_cleaning_param,
|
|
.get_cleaning_param = cleaning_policy_alru_get_cleaning_param,
|
|
.perform_cleaning = cleaning_alru_perform_cleaning,
|
|
.name = "alru",
|
|
},
|
|
[ocf_cleaning_acp] = {
|
|
.setup = cleaning_policy_acp_setup,
|
|
.init_cache_block = cleaning_policy_acp_init_cache_block,
|
|
.purge_cache_block = cleaning_policy_acp_purge_block,
|
|
.purge_range = cleaning_policy_acp_purge_range,
|
|
.set_hot_cache_line = cleaning_policy_acp_set_hot_cache_line,
|
|
.initialize = cleaning_policy_acp_initialize,
|
|
.deinitialize = cleaning_policy_acp_deinitialize,
|
|
.set_cleaning_param = cleaning_policy_acp_set_cleaning_param,
|
|
.get_cleaning_param = cleaning_policy_acp_get_cleaning_param,
|
|
.add_core = cleaning_policy_acp_add_core,
|
|
.remove_core = cleaning_policy_acp_remove_core,
|
|
.perform_cleaning = cleaning_policy_acp_perform_cleaning,
|
|
.name = "acp",
|
|
},
|
|
};
|
|
|
|
int ocf_start_cleaner(struct ocf_cache *cache)
|
|
{
|
|
return ctx_cleaner_init(cache->owner, &cache->cleaner);
|
|
}
|
|
|
|
void ocf_stop_cleaner(struct ocf_cache *cache)
|
|
{
|
|
ctx_cleaner_stop(cache->owner, &cache->cleaner);
|
|
}
|
|
|
|
void ocf_cleaner_set_priv(ocf_cleaner_t c, void *priv)
|
|
{
|
|
OCF_CHECK_NULL(c);
|
|
c->priv = priv;
|
|
}
|
|
|
|
void *ocf_cleaner_get_priv(ocf_cleaner_t c)
|
|
{
|
|
OCF_CHECK_NULL(c);
|
|
return c->priv;
|
|
}
|
|
|
|
ocf_cache_t ocf_cleaner_get_cache(ocf_cleaner_t c)
|
|
{
|
|
OCF_CHECK_NULL(c);
|
|
return container_of(c, struct ocf_cache, cleaner);
|
|
}
|
|
|
|
static int _ocf_cleaner_run_check_dirty_inactive(struct ocf_cache *cache)
|
|
{
|
|
int i;
|
|
|
|
if (!env_bit_test(ocf_cache_state_incomplete, &cache->cache_state))
|
|
return 0;
|
|
|
|
for (i = 0; i < OCF_CORE_MAX; ++i) {
|
|
if (!env_bit_test(i, cache->conf_meta->valid_object_bitmap))
|
|
continue;
|
|
|
|
if (cache->core[i].opened && env_atomic_read(&(cache->
|
|
core_runtime_meta[i].dirty_clines))) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
uint32_t ocf_cleaner_run(ocf_cleaner_t c, uint32_t io_queue)
|
|
{
|
|
struct ocf_cache *cache;
|
|
ocf_cleaning_t clean_type;
|
|
int sleep = SLEEP_TIME_MS;
|
|
|
|
cache = ocf_cleaner_get_cache(c);
|
|
|
|
/* Do not involve cleaning when cache is not running
|
|
* (error, etc.).
|
|
*/
|
|
if (!env_bit_test(ocf_cache_state_running, &cache->cache_state) ||
|
|
ocf_mngt_is_cache_locked(cache)) {
|
|
return SLEEP_TIME_MS;
|
|
}
|
|
|
|
/* Sleep in case there is management operation in progress. */
|
|
if (env_rwsem_down_write_trylock(&cache->lock) == 0)
|
|
return SLEEP_TIME_MS;
|
|
|
|
if (_ocf_cleaner_run_check_dirty_inactive(cache)) {
|
|
env_rwsem_up_write(&cache->lock);
|
|
return SLEEP_TIME_MS;
|
|
}
|
|
|
|
clean_type = cache->conf_meta->cleaning_policy_type;
|
|
|
|
ENV_BUG_ON(clean_type >= ocf_cleaning_max);
|
|
|
|
/* Call cleaning. */
|
|
if (cleaning_policy_ops[clean_type].perform_cleaning) {
|
|
sleep = cleaning_policy_ops[clean_type].
|
|
perform_cleaning(cache, io_queue);
|
|
}
|
|
|
|
env_rwsem_up_write(&cache->lock);
|
|
|
|
return sleep;
|
|
}
|
|
|