Switching mechanism for promotion policies

Signed-off-by: Jan Musial <jan.musial@intel.com>
This commit is contained in:
Jan Musial
2019-08-26 13:52:11 +02:00
parent e3a20c0da0
commit a1d3cf0c4d
12 changed files with 252 additions and 26 deletions

View File

@@ -17,6 +17,9 @@
* and insert elements from the beggining. So lifetime of a core line varies
* depending on insertion and removal rate.
*
* and rb_pointer which is index to ring_buffer element that is going to be used
* for next insertion.
*
* Operations:
* - query(core_id, core_lba):
* Check if core line is present in structure, bump up counter and
@@ -55,9 +58,10 @@
* | ^ | ^
* |________| |________|
*
* Since rb_pointer is pointing to occupied rb slot we need to write-lock hash
* bucket I associated with this slot and remove it from collision list.
* We've gained an empty slot and we use slot X for new hash H entry.
* We will attempt to insert new element at rb_pointer. Since rb_pointer is
* pointing to occupied rb slot we need to write-lock hash bucket I associated
* with this slot and remove it from collision list. We've gained an empty slot
* and we use slot X for new hash H entry.
*
* +--+--+--+--+--+--+--+--+--+--+
* | | |I | | | | | |H | | hash_map
@@ -109,7 +113,8 @@ ocf_error_t hash_init(uint64_t hash_size, nhit_hash_t *ctx)
{
int result = 0;
struct nhit_hash *new_ctx;
uint64_t i;
uint32_t i;
int64_t i_locks;
new_ctx = env_vzalloc(sizeof(*new_ctx));
if (!new_ctx) {
@@ -138,9 +143,10 @@ ocf_error_t hash_init(uint64_t hash_size, nhit_hash_t *ctx)
goto dealloc_hash;
}
for (i = 0; i < new_ctx->hash_entries; i++) {
if (env_rwsem_init(&new_ctx->hash_locks[i])) {
for (i_locks = 0; i_locks < new_ctx->hash_entries; i_locks++) {
if (env_rwsem_init(&new_ctx->hash_locks[i_locks])) {
result = -OCF_ERR_UNKNOWN;
i_locks--;
goto dealloc_locks;
}
}
@@ -164,8 +170,8 @@ ocf_error_t hash_init(uint64_t hash_size, nhit_hash_t *ctx)
return 0;
dealloc_locks:
for (i = 0; i < new_ctx->hash_entries; i++)
ENV_BUG_ON(env_rwsem_destroy(&new_ctx->hash_locks[i]));
for (; i_locks >= 0; i_locks--)
ENV_BUG_ON(env_rwsem_destroy(&new_ctx->hash_locks[i_locks]));
env_vfree(new_ctx->hash_locks);
dealloc_hash:
env_vfree(new_ctx->hash_map);
@@ -350,12 +356,12 @@ void hash_insert(nhit_hash_t ctx, ocf_core_id_t core_id, uint64_t core_lba)
bool hash_query(nhit_hash_t ctx, ocf_core_id_t core_id, uint64_t core_lba,
int32_t *counter)
{
OCF_CHECK_NULL(counter);
ocf_cache_line_t hash = hash_function(core_id, core_lba,
ctx->hash_entries);
uint64_t rb_idx;
OCF_CHECK_NULL(counter);
env_rwsem_down_read(&ctx->hash_locks[hash]);
rb_idx = core_line_lookup(ctx, core_id, core_lba);

View File

@@ -13,15 +13,12 @@
#define NHIT_MAPPING_RATIO 2
#define NHIT_MIN_THRESHOLD 1
#define NHIT_MAX_THRESHOLD 1000
#define NHIT_THRESHOLD_DEFAULT 3
struct nhit_policy_context {
nhit_hash_t hash_map;
/* Configurable parameters */
env_atomic insertion_threshold;
env_atomic64 trigger_threshold;
};
ocf_error_t nhit_init(ocf_cache_t cache, ocf_promotion_policy_t policy)
@@ -41,6 +38,9 @@ ocf_error_t nhit_init(ocf_cache_t cache, ocf_promotion_policy_t policy)
goto dealloc_ctx;
env_atomic_set(&ctx->insertion_threshold, NHIT_THRESHOLD_DEFAULT);
env_atomic64_set(&ctx->trigger_threshold,
OCF_DIV_ROUND_UP((NHIT_TRIGGER_DEFAULT *
ocf_metadata_get_cachelines_count(cache)), 100));
policy->ctx = ctx;
@@ -71,7 +71,7 @@ ocf_error_t nhit_set_param(ocf_promotion_policy_t policy, uint8_t param_id,
switch (param_id) {
case nhit_insertion_threshold:
if (param_value > NHIT_MIN_THRESHOLD &&
if (param_value >= NHIT_MIN_THRESHOLD &&
param_value < NHIT_MAX_THRESHOLD) {
env_atomic_set(&ctx->insertion_threshold, param_value);
} else {
@@ -81,6 +81,22 @@ ocf_error_t nhit_set_param(ocf_promotion_policy_t policy, uint8_t param_id,
}
break;
case nhit_trigger_threshold:
if (param_value >= NHIT_MIN_TRIGGER &&
param_value < NHIT_MAX_TRIGGER) {
env_atomic64_set(&ctx->trigger_threshold,
OCF_DIV_ROUND_UP((param_value *
ocf_metadata_get_cachelines_count(policy->owner)),
100));
} else {
ocf_cache_log(policy->owner, log_err, "Invalid nhit "
"promotion policy insertion trigger "
"threshold!\n");
result = -OCF_ERR_INVAL;
}
break;
default:
ocf_cache_log(policy->owner, log_err, "Invalid nhit "
"promotion policy parameter (%u)!\n",
@@ -163,6 +179,12 @@ bool nhit_req_should_promote(ocf_promotion_policy_t policy,
bool result = true;
uint32_t i;
uint64_t core_line;
uint64_t occupied_cachelines =
ocf_metadata_get_cachelines_count(policy->owner) -
policy->owner->device->freelist_part->curr_size;
if (occupied_cachelines > env_atomic64_read(&ctx->trigger_threshold))
return true;
for (i = 0, core_line = req->core_line_first;
core_line <= req->core_line_last; core_line++, i++) {

View File

@@ -10,11 +10,6 @@
#include "../../ocf_request.h"
#include "../promotion.h"
enum nhit_param {
nhit_insertion_threshold,
nhit_param_max
};
ocf_error_t nhit_init(ocf_cache_t cache, ocf_promotion_policy_t policy);
void nhit_deinit(ocf_promotion_policy_t policy);

View File

@@ -11,6 +11,7 @@
struct ocf_promotion_policy {
ocf_cache_t owner;
ocf_promotion_t type;
void *ctx;
};

View File

@@ -55,6 +55,35 @@ void ocf_promotion_deinit(ocf_promotion_policy_t 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;
prev_policy = cache->conf_meta->promotion_policy_type;
if (ocf_promotion_policies[prev_policy].deinit)
ocf_promotion_policies[prev_policy].deinit(policy);
cache->conf_meta->promotion_policy_type = type;
if (ocf_promotion_policies[type].init)
result = ocf_promotion_policies[type].init(cache, policy);
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_promotion_policy_t policy,
uint8_t param_id, uint64_t param_value)
{

View File

@@ -31,6 +31,16 @@ ocf_error_t ocf_promotion_init(ocf_cache_t cache, ocf_promotion_policy_t *policy
*/
void ocf_promotion_deinit(ocf_promotion_policy_t policy);
/**
* @brief Switch promotion policy to type. On failure will fall back to 'always'
*
* @param[in] policy promotion policy handle
* @param[in] type promotion policy target type
*
* @retval ocf_error_t
*/
ocf_error_t ocf_promotion_set_policy(ocf_promotion_policy_t policy,
ocf_promotion_t type);
/**
* @brief Set promotion policy parameter
*