ocf/src/promotion/promotion.c
Michal Mielewczyk e16d4e6dda Initialize promotion policy on cache attach.
Signed-off-by: Michal Mielewczyk <michal.mielewczyk@intel.com>
2019-10-01 06:11:53 -04:00

164 lines
3.7 KiB
C

/*
* Copyright(c) 2019 Intel Corporation
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#include "../metadata/metadata.h"
#include "promotion.h"
#include "ops.h"
#include "nhit/nhit.h"
struct promotion_policy_ops ocf_promotion_policies[ocf_promotion_max] = {
[ocf_promotion_always] = {
.name = "always",
},
[ocf_promotion_nhit] = {
.name = "nhit",
.setup = nhit_setup,
.init = nhit_init,
.deinit = nhit_deinit,
.set_param = nhit_set_param,
.get_param = nhit_get_param,
.req_purge = nhit_req_purge,
.req_should_promote = nhit_req_should_promote,
},
};
ocf_error_t ocf_promotion_init(ocf_cache_t cache, ocf_promotion_t type)
{
ocf_promotion_policy_t policy;
ocf_error_t result = 0;
ENV_BUG_ON(type >= ocf_promotion_max);
policy = env_vmalloc(sizeof(*policy));
if (!policy)
return -OCF_ERR_NO_MEM;
policy->type = type;
policy->owner = cache;
policy->config =
(void *)&cache->conf_meta->promotion[type].data;
cache->promotion_policy = policy;
if (ocf_promotion_policies[type].init)
result = ocf_promotion_policies[type].init(cache);
if (result) {
env_vfree(cache->promotion_policy);
cache->promotion_policy = NULL;
}
return result;
}
void ocf_promotion_deinit(ocf_promotion_policy_t policy)
{
ocf_promotion_t type = policy->type;
ENV_BUG_ON(type >= ocf_promotion_max);
if (ocf_promotion_policies[type].deinit)
ocf_promotion_policies[type].deinit(policy);
env_vfree(policy);
}
ocf_error_t ocf_promotion_set_policy(ocf_promotion_policy_t policy,
ocf_promotion_t type)
{
ocf_error_t result = 0;
ocf_cache_t cache = policy->owner;
ocf_promotion_t prev_policy;
if (type >= ocf_promotion_max)
return -OCF_ERR_INVAL;
prev_policy = cache->conf_meta->promotion_policy_type;
if (type == prev_policy) {
ocf_cache_log(cache, log_info, "Promotion policy '%s' is already set\n",
ocf_promotion_policies[type].name);
return 0;
}
if (ocf_promotion_policies[prev_policy].deinit)
ocf_promotion_policies[prev_policy].deinit(policy);
cache->conf_meta->promotion_policy_type = type;
policy->type = type;
if (ocf_promotion_policies[type].init)
result = ocf_promotion_policies[type].init(cache);
if (result) {
ocf_cache_log(cache, log_err,
"Error switching to new promotion policy\n");
ocf_cache_log(cache, log_err,
"Falling back to 'always' promotion policy\n");
cache->conf_meta->promotion_policy_type = ocf_promotion_always;
policy->type = ocf_promotion_always;
}
return result;
}
ocf_error_t ocf_promotion_set_param(ocf_cache_t cache, ocf_promotion_t type,
uint8_t param_id, uint32_t param_value)
{
ocf_error_t result = -OCF_ERR_INVAL;
ENV_BUG_ON(type >= ocf_promotion_max);
if (ocf_promotion_policies[type].set_param) {
result = ocf_promotion_policies[type].set_param(cache, param_id,
param_value);
}
return result;
}
ocf_error_t ocf_promotion_get_param(ocf_cache_t cache, ocf_promotion_t type,
uint8_t param_id, uint32_t *param_value)
{
ocf_error_t result = -OCF_ERR_INVAL;
ENV_BUG_ON(type >= ocf_promotion_max);
if (ocf_promotion_policies[type].get_param) {
result = ocf_promotion_policies[type].get_param(cache, param_id,
param_value);
}
return result;
}
void ocf_promotion_req_purge(ocf_promotion_policy_t policy,
struct ocf_request *req)
{
ocf_promotion_t type = policy->type;
ENV_BUG_ON(type >= ocf_promotion_max);
if (ocf_promotion_policies[type].req_purge)
ocf_promotion_policies[type].req_purge(policy, req);
}
bool ocf_promotion_req_should_promote(ocf_promotion_policy_t policy,
struct ocf_request *req)
{
ocf_promotion_t type = policy->type;
bool result = true;
ENV_BUG_ON(type >= ocf_promotion_max);
if (ocf_promotion_policies[type].req_should_promote) {
result = ocf_promotion_policies[type].req_should_promote(policy,
req);
}
return result;
}