Initialize promotion policy on cache attach.

Signed-off-by: Michal Mielewczyk <michal.mielewczyk@intel.com>
This commit is contained in:
Michal Mielewczyk 2019-09-30 10:10:02 -04:00
parent dfc55538ce
commit e16d4e6dda
10 changed files with 115 additions and 99 deletions

View File

@ -813,29 +813,29 @@ ocf_promotion_t ocf_mngt_cache_promotion_get_policy(ocf_cache_t cache);
* @brief Set promotion policy parameter for given cache
*
* @param[in] cache Cache handle
* @param[in] param_id Promotion policy parameter id
* @param[in] type Promotion policy type
* @param[in] param_id Promotion policy parameter id
* @param[in] param_value Promotion policy parameter value
*
* @retval 0 Parameter has been set successfully
* @retval Non-zero Error occurred and parameter has not been set
*/
int ocf_mngt_cache_promotion_set_param(ocf_cache_t cache, uint8_t param_id,
ocf_promotion_t type, uint32_t param_value);
int ocf_mngt_cache_promotion_set_param(ocf_cache_t cache, ocf_promotion_t type,
uint8_t param_id, uint32_t param_value);
/**
* @brief Get promotion policy parameter for given cache
*
* @param[in] cache Cache handle
* @param[in] param_id Promotion policy parameter id
* @param[in] type Promotion policy type
* @param[in] param_id Promotion policy parameter id
* @param[out] param_value Variable to store parameter value
*
* @retval 0 Parameter has been retrieved successfully
* @retval Non-zero Error occurred and parameter has not been retrieved
*/
int ocf_mngt_cache_promotion_get_param(ocf_cache_t cache, uint8_t param_id,
ocf_promotion_t type, uint32_t *param_value);
int ocf_mngt_cache_promotion_get_param(ocf_cache_t cache, ocf_promotion_t type,
uint8_t param_id, uint32_t *param_value);
/**
* @brief IO class configuration

View File

@ -117,6 +117,9 @@ struct ocf_cache_attach_context {
bool cleaner_started : 1;
/*!< Cleaner has been started */
bool promotion_initialized : 1;
/*!< Promotion policy has been started */
bool cores_opened : 1;
/*!< underlying cores are opened (happens only during
* load or recovery
@ -244,19 +247,16 @@ static void __init_eviction_policy(ocf_cache_t cache,
cache->conf_meta->eviction_policy_type = eviction;
}
static ocf_error_t __init_promotion_policy(ocf_cache_t cache)
static void __setup_promotion_policy(ocf_cache_t cache)
{
int i;
OCF_ASSERT_PLUGGED(cache);
ENV_BUG_ON(cache->promotion_policy);
OCF_CHECK_NULL(cache);
for (i = 0; i < ocf_promotion_max; i++) {
if (ocf_promotion_policies[i].setup)
ocf_promotion_policies[i].setup(cache);
}
return ocf_promotion_init(cache, &cache->promotion_policy);
}
static void __deinit_promotion_policy(ocf_cache_t cache)
@ -318,13 +318,7 @@ static ocf_error_t init_attached_data_structures(ocf_cache_t cache,
}
__init_eviction_policy(cache, eviction_policy);
result =__init_promotion_policy(cache);
if (result) {
ocf_cache_log(cache, log_err,
"Cannot initialize promotion policy\n");
__deinit_cleaning_policy(cache);
return result;
}
__setup_promotion_policy(cache);
return 0;
}
@ -476,13 +470,6 @@ void _ocf_mngt_init_instance_load_complete(void *priv, int error)
__init_freelist(cache);
result = ocf_promotion_init(cache, &cache->promotion_policy);
if (result) {
ocf_cache_log(cache, log_err,
"Cannot initialize promotion policy\n");
OCF_PL_FINISH_RET(context->pipeline, result);
}
cleaning_policy = cache->conf_meta->cleaning_policy_type;
if (!cleaning_policy_ops[cleaning_policy].initialize)
goto out;
@ -495,7 +482,6 @@ void _ocf_mngt_init_instance_load_complete(void *priv, int error)
if (result) {
ocf_cache_log(cache, log_err,
"Cannot initialize cleaning policy\n");
__deinit_promotion_policy(cache);
OCF_PL_FINISH_RET(context->pipeline, result);
}
@ -1148,6 +1134,9 @@ static void _ocf_mngt_attach_handle_error(
if (context->flags.cleaner_started)
ocf_stop_cleaner(cache);
if (context->flags.promotion_initialized)
__deinit_promotion_policy(cache);
if (context->flags.cores_opened)
_ocf_mngt_close_all_uninitialized_cores(cache);
@ -1178,6 +1167,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;
INIT_LIST_HEAD(&cache->io_queues);
@ -1364,6 +1354,14 @@ static void _ocf_mngt_attach_init_instance(ocf_pipeline_t pipeline,
}
context->flags.cleaner_started = true;
result = ocf_promotion_init(cache, cache->conf_meta->promotion_policy_type);
if (result) {
ocf_cache_log(cache, log_err,
"Cannot initialize promotion policy\n");
OCF_PL_FINISH_RET(context->pipeline, result);
}
context->flags.promotion_initialized = true;
switch (cache->device->init_mode) {
case ocf_init_mode_init:
case ocf_init_mode_metadata_volatile:
@ -1834,6 +1832,7 @@ static void _ocf_mngt_cache_load_log(ocf_cache_t cache)
ocf_cache_mode_t cache_mode = ocf_cache_get_mode(cache);
ocf_eviction_t eviction_type = cache->conf_meta->eviction_policy_type;
ocf_cleaning_t cleaning_type = cache->conf_meta->cleaning_policy_type;
ocf_promotion_t promotion_type = cache->conf_meta->promotion_policy_type;
ocf_cache_log(cache, log_info, "Successfully loaded\n");
ocf_cache_log(cache, log_info, "Cache mode : %s\n",
@ -1842,6 +1841,8 @@ static void _ocf_mngt_cache_load_log(ocf_cache_t cache)
evict_policy_ops[eviction_type].name);
ocf_cache_log(cache, log_info, "Cleaning policy : %s\n",
cleaning_policy_ops[cleaning_type].name);
ocf_cache_log(cache, log_info, "Promotion policy : %s\n",
ocf_promotion_policies[promotion_type].name);
ocf_core_visit(cache, _ocf_mngt_cache_load_core_log,
cache, false);
}
@ -2282,28 +2283,28 @@ ocf_promotion_t ocf_mngt_cache_promotion_get_policy(ocf_cache_t cache)
return result;
}
int ocf_mngt_cache_promotion_get_param(ocf_cache_t cache, uint8_t param_id,
ocf_promotion_t type, uint32_t *param_value)
int ocf_mngt_cache_promotion_get_param(ocf_cache_t cache, ocf_promotion_t type,
uint8_t param_id, uint32_t *param_value)
{
int result;
ocf_metadata_start_shared_access(&cache->metadata.lock);
result = ocf_promotion_get_param(cache, param_id, type, param_value);
result = ocf_promotion_get_param(cache, type, param_id, param_value);
ocf_metadata_end_shared_access(&cache->metadata.lock);
return result;
}
int ocf_mngt_cache_promotion_set_param(ocf_cache_t cache, uint8_t param_id,
ocf_promotion_t type, uint32_t param_value)
int ocf_mngt_cache_promotion_set_param(ocf_cache_t cache, ocf_promotion_t type,
uint8_t param_id, uint32_t param_value)
{
int result;
ocf_metadata_start_exclusive_access(&cache->metadata.lock);
result = ocf_promotion_set_param(cache, param_id, type, param_value);
result = ocf_promotion_set_param(cache, type, param_id, param_value);
ocf_metadata_end_exclusive_access(&cache->metadata.lock);

View File

@ -27,7 +27,7 @@ void nhit_setup(ocf_cache_t cache)
cfg->trigger_threshold = OCF_NHIT_TRIGGER_DEFAULT;
}
ocf_error_t nhit_init(ocf_cache_t cache, ocf_promotion_policy_t policy)
ocf_error_t nhit_init(ocf_cache_t cache)
{
struct nhit_policy_context *ctx;
int result = 0;
@ -43,7 +43,7 @@ ocf_error_t nhit_init(ocf_cache_t cache, ocf_promotion_policy_t policy)
if (result)
goto dealloc_ctx;
policy->ctx = ctx;
cache->promotion_policy->ctx = ctx;
return 0;
@ -172,7 +172,7 @@ static bool core_line_should_promote(ocf_promotion_policy_t policy,
bool hit;
int32_t counter;
cfg = (void *)&policy->owner->conf_meta->promotion[ocf_promotion_nhit].data;
cfg = (struct nhit_promotion_policy_config*)policy->config;
ctx = policy->ctx;
hit = nhit_hash_query(ctx->hash_map, core_id, core_lba, &counter);
@ -197,7 +197,7 @@ bool nhit_req_should_promote(ocf_promotion_policy_t policy,
ocf_metadata_collision_table_entries(policy->owner) -
ocf_freelist_num_free(policy->owner->freelist);
cfg = (void *)&policy->owner->conf_meta->promotion[ocf_promotion_nhit].data;
cfg = (struct nhit_promotion_policy_config*)policy->config;
if (occupied_cachelines < OCF_DIV_ROUND_UP(
((uint64_t)cfg->trigger_threshold *

View File

@ -13,7 +13,7 @@
void nhit_setup(ocf_cache_t cache);
ocf_error_t nhit_init(ocf_cache_t cache, ocf_promotion_policy_t policy);
ocf_error_t nhit_init(ocf_cache_t cache);
void nhit_deinit(ocf_promotion_policy_t policy);

View File

@ -13,6 +13,10 @@ struct ocf_promotion_policy {
ocf_cache_t owner;
ocf_promotion_t type;
void *config;
/* Pointer to config values stored in cache superblock */
void *ctx;
};
@ -23,7 +27,7 @@ struct promotion_policy_ops {
void (*setup)(ocf_cache_t cache);
/*!< initialize promotion policy default config */
ocf_error_t (*init)(ocf_cache_t cache, ocf_promotion_policy_t policy);
ocf_error_t (*init)(ocf_cache_t cache);
/*!< Allocate and initialize promotion policy */
void (*deinit)(ocf_promotion_policy_t policy);

View File

@ -25,22 +25,30 @@ struct promotion_policy_ops ocf_promotion_policies[ocf_promotion_max] = {
},
};
ocf_error_t ocf_promotion_init(ocf_cache_t cache, ocf_promotion_policy_t *policy)
ocf_error_t ocf_promotion_init(ocf_cache_t cache, ocf_promotion_t type)
{
ocf_promotion_t type = cache->conf_meta->promotion_policy_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)
policy = env_vmalloc(sizeof(*policy));
if (!policy)
return -OCF_ERR_NO_MEM;
(*policy)->type = type;
(*policy)->owner = cache;
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, *policy);
result = ocf_promotion_policies[type].init(cache);
if (result) {
env_vfree(cache->promotion_policy);
cache->promotion_policy = NULL;
}
return result;
}
@ -82,7 +90,7 @@ ocf_error_t ocf_promotion_set_policy(ocf_promotion_policy_t policy,
policy->type = type;
if (ocf_promotion_policies[type].init)
result = ocf_promotion_policies[type].init(cache, policy);
result = ocf_promotion_policies[type].init(cache);
if (result) {
ocf_cache_log(cache, log_err,
@ -96,8 +104,8 @@ ocf_error_t ocf_promotion_set_policy(ocf_promotion_policy_t policy,
return result;
}
ocf_error_t ocf_promotion_set_param(ocf_cache_t cache, uint8_t param_id,
ocf_promotion_t type, uint32_t param_value)
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;
@ -111,8 +119,8 @@ ocf_error_t ocf_promotion_set_param(ocf_cache_t cache, uint8_t param_id,
return result;
}
ocf_error_t ocf_promotion_get_param(ocf_cache_t cache, uint8_t param_id,
ocf_promotion_t type, uint32_t *param_value)
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;

View File

@ -34,11 +34,11 @@ void ocf_promotion_setup(ocf_cache_t cache);
* been set.
*
* @param[in] cache OCF cache instance
* @param[out] param initialized policy handle
* @param[in] type type of promotion policy to initialize
*
* @retval ocf_error_t
*/
ocf_error_t ocf_promotion_init(ocf_cache_t cache, ocf_promotion_policy_t *policy);
ocf_error_t ocf_promotion_init(ocf_cache_t cache, ocf_promotion_t type);
/**
* @brief Stop, deinitialize and free promotion policy structures.
@ -63,27 +63,27 @@ ocf_error_t ocf_promotion_set_policy(ocf_promotion_policy_t policy,
* @brief Set promotion policy parameter
*
* @param[in] cache cache handle
* @param[in] type id of promotion policy to be configured
* @param[in] param_id id of parameter to be set
* @param[in] type id of propmotion policy to be configured
* @param[in] param_value value of parameter to be set
*
* @retval ocf_error_t
*/
ocf_error_t ocf_promotion_set_param(ocf_cache_t cache, uint8_t param_id,
ocf_promotion_t type, uint32_t param_value);
ocf_error_t ocf_promotion_set_param(ocf_cache_t cache, ocf_promotion_t type,
uint8_t param_id, uint32_t param_value);
/**
* @brief Get promotion policy parameter
*
* @param[in] cache cache handle
* @param[in] type id of promotion policy to be configured
* @param[in] param_id id of parameter to be set
* @param[in] type id of propmotion policy to be configured
* @param[out] param_value value of parameter to be set
*
* @retval ocf_error_t
*/
ocf_error_t ocf_promotion_get_param(ocf_cache_t cache, uint8_t param_id,
ocf_promotion_t type, uint32_t *param_value);
ocf_error_t ocf_promotion_get_param(ocf_cache_t cache, ocf_promotion_t type,
uint8_t param_id, uint32_t *param_value);
/**
* @brief Update promotion policy after cache lines have been promoted to cache

View File

@ -255,7 +255,7 @@ class Cache:
param_value = c_uint64()
status = self.owner.lib.ocf_mngt_cache_promotion_get_param(
self.cache_handle, param_id, promotion_type, byref(param_value)
self.cache_handle, promotion_type, param_id, byref(param_value)
)
self.read_unlock()
@ -264,11 +264,11 @@ class Cache:
return param_value
def set_promotion_policy_param(self, param_id, promotion_type, param_value):
def set_promotion_policy_param(self, promotion_type, param_id, param_value):
self.write_lock()
status = self.owner.lib.ocf_mngt_cache_promotion_set_param(
self.cache_handle, param_id, promotion_type, param_value
self.cache_handle, promotion_type, param_id, param_value
)
self.write_unlock()

View File

@ -186,10 +186,10 @@ def test_promoted_after_hits_various_thresholds(
# Step 2
cache.set_promotion_policy_param(
NhitParams.TRIGGER_THRESHOLD, PromotionPolicy.NHIT, fill_percentage
PromotionPolicy.NHIT, NhitParams.TRIGGER_THRESHOLD, fill_percentage
)
cache.set_promotion_policy_param(
NhitParams.INSERTION_THRESHOLD, PromotionPolicy.NHIT, insertion_threshold
PromotionPolicy.NHIT, NhitParams.INSERTION_THRESHOLD, insertion_threshold
)
# Step 3
fill_cache(cache, fill_percentage / 100)
@ -284,10 +284,10 @@ def test_partial_hit_promotion(pyocf_ctx):
# Step 3
cache.set_promotion_policy(PromotionPolicy.NHIT)
cache.set_promotion_policy_param(
NhitParams.TRIGGER_THRESHOLD, PromotionPolicy.NHIT, 0
PromotionPolicy.NHIT, NhitParams.TRIGGER_THRESHOLD, 0
)
cache.set_promotion_policy_param(
NhitParams.INSERTION_THRESHOLD, PromotionPolicy.NHIT, 100
PromotionPolicy.NHIT, NhitParams.INSERTION_THRESHOLD, 100
)
# Step 4

View File

@ -5,18 +5,22 @@
import pytest
from pyocf.types.cache import Cache, CacheMode, CleaningPolicy,\
AlruParams, AcpParams, PromotionPolicy, NhitParams, ConfValidValues
from pyocf.types.cache import (
Cache,
CacheMode,
CleaningPolicy,
AlruParams,
AcpParams,
PromotionPolicy,
NhitParams,
ConfValidValues,
)
from pyocf.types.core import Core
from pyocf.types.volume import Volume
from pyocf.utils import Size as S
from tests.utils import generate_random_numbers
from pyocf.types.shared import OcfError, CacheLineSize, SeqCutOffPolicy
from ctypes import (
c_uint64,
c_uint32,
c_uint8
)
from ctypes import c_uint64, c_uint32, c_uint8
@pytest.mark.parametrize("cm", CacheMode)
@ -31,9 +35,7 @@ def test_neg_change_cache_mode(pyocf_ctx, cm, cls):
"""
# Start cache device
cache_device = Volume(S.from_MiB(30))
cache = Cache.start_on_device(
cache_device, cache_mode=cm, cache_line_size=cls
)
cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls)
# Change cache mode to invalid one and check if failed
for i in generate_random_numbers(c_uint32):
@ -56,9 +58,7 @@ def test_neg_set_cleaning_policy(pyocf_ctx, cm, cls):
"""
# Start cache device
cache_device = Volume(S.from_MiB(30))
cache = Cache.start_on_device(
cache_device, cache_mode=cm, cache_line_size=cls
)
cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls)
# Set cleaning policy to invalid one and check if failed
for i in generate_random_numbers(c_uint32):
@ -106,9 +106,7 @@ def test_neg_cache_set_seq_cut_off_policy(pyocf_ctx, cm, cls):
"""
# Start cache device
cache_device = Volume(S.from_MiB(30))
cache = Cache.start_on_device(
cache_device, cache_mode=cm, cache_line_size=cls
)
cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls)
# Create 2 core devices
core_device1 = Volume(S.from_MiB(10))
@ -141,9 +139,7 @@ def test_neg_core_set_seq_cut_off_policy(pyocf_ctx, cm, cls):
"""
# Start cache device
cache_device = Volume(S.from_MiB(30))
cache = Cache.start_on_device(
cache_device, cache_mode=cm, cache_line_size=cls
)
cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls)
# Create core device
core_device = Volume(S.from_MiB(10))
@ -173,9 +169,7 @@ def test_neg_set_alru_param(pyocf_ctx, cm, cls):
"""
# Start cache device
cache_device = Volume(S.from_MiB(30))
cache = Cache.start_on_device(
cache_device, cache_mode=cm, cache_line_size=cls
)
cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls)
# Change invalid alru param and check if failed
for i in generate_random_numbers(c_uint32):
@ -198,9 +192,7 @@ def test_neg_set_acp_param(pyocf_ctx, cm, cls):
"""
# Start cache device
cache_device = Volume(S.from_MiB(30))
cache = Cache.start_on_device(
cache_device, cache_mode=cm, cache_line_size=cls
)
cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls)
# Change invalid acp param and check if failed
for i in generate_random_numbers(c_uint32):
@ -223,9 +215,7 @@ def test_neg_set_promotion_policy(pyocf_ctx, cm, cls):
"""
# Start cache device
cache_device = Volume(S.from_MiB(30))
cache = Cache.start_on_device(
cache_device, cache_mode=cm, cache_line_size=cls
)
cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls)
# Change to invalid promotion policy and check if failed
for i in generate_random_numbers(c_uint32):
@ -249,7 +239,10 @@ def test_neg_set_nhit_promotion_policy_param(pyocf_ctx, cm, cls):
# Start cache device
cache_device = Volume(S.from_MiB(30))
cache = Cache.start_on_device(
cache_device, cache_mode=cm, cache_line_size=cls, promotion_policy=PromotionPolicy.NHIT
cache_device,
cache_mode=cm,
cache_line_size=cls,
promotion_policy=PromotionPolicy.NHIT,
)
# Set invalid promotion policy param id and check if failed
@ -257,7 +250,7 @@ def test_neg_set_nhit_promotion_policy_param(pyocf_ctx, cm, cls):
if i in [item.value for item in NhitParams]:
continue
with pytest.raises(OcfError, match="Error setting promotion policy parameter"):
cache.set_promotion_policy_param(i, 1)
cache.set_promotion_policy_param(PromotionPolicy.NHIT, i, 1)
@pytest.mark.parametrize("cm", CacheMode)
@ -275,7 +268,10 @@ def test_neg_set_nhit_promotion_policy_param_trigger(pyocf_ctx, cm, cls):
# Start cache device
cache_device = Volume(S.from_MiB(30))
cache = Cache.start_on_device(
cache_device, cache_mode=cm, cache_line_size=cls, promotion_policy=PromotionPolicy.NHIT
cache_device,
cache_mode=cm,
cache_line_size=cls,
promotion_policy=PromotionPolicy.NHIT,
)
# Set to invalid promotion policy trigger threshold and check if failed
@ -283,7 +279,9 @@ def test_neg_set_nhit_promotion_policy_param_trigger(pyocf_ctx, cm, cls):
if i in ConfValidValues.promotion_nhit_trigger_threshold_range:
continue
with pytest.raises(OcfError, match="Error setting promotion policy parameter"):
cache.set_promotion_policy_param(NhitParams.TRIGGER_THRESHOLD, i)
cache.set_promotion_policy_param(
PromotionPolicy.NHIT, NhitParams.TRIGGER_THRESHOLD, i
)
@pytest.mark.parametrize("cm", CacheMode)
@ -301,7 +299,10 @@ def test_neg_set_nhit_promotion_policy_param_threshold(pyocf_ctx, cm, cls):
# Start cache device
cache_device = Volume(S.from_MiB(30))
cache = Cache.start_on_device(
cache_device, cache_mode=cm, cache_line_size=cls, promotion_policy=PromotionPolicy.NHIT
cache_device,
cache_mode=cm,
cache_line_size=cls,
promotion_policy=PromotionPolicy.NHIT,
)
# Set to invalid promotion policy insertion threshold and check if failed
@ -309,4 +310,6 @@ def test_neg_set_nhit_promotion_policy_param_threshold(pyocf_ctx, cm, cls):
if i in ConfValidValues.promotion_nhit_insertion_threshold_range:
continue
with pytest.raises(OcfError, match="Error setting promotion policy parameter"):
cache.set_promotion_policy_param(NhitParams.INSERTION_THRESHOLD, i)
cache.set_promotion_policy_param(
PromotionPolicy.NHIT, NhitParams.INSERTION_THRESHOLD, i
)