Add promotion policy API and use it in I/O path
Promotion policy is supposed to perform ALRU noise filtering by eliminating one-hit wonders being added to cache and polluting it. Signed-off-by: Jan Musial <jan.musial@intel.com>
This commit is contained in:
parent
999f3f7245
commit
917cbd859a
@ -193,7 +193,7 @@ typedef enum {
|
|||||||
} ocf_seq_cutoff_policy;
|
} ocf_seq_cutoff_policy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OCF supported eviction types
|
* OCF supported eviction policy types
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ocf_eviction_lru = 0,
|
ocf_eviction_lru = 0,
|
||||||
@ -206,6 +206,23 @@ typedef enum {
|
|||||||
/*!< Default eviction policy */
|
/*!< Default eviction policy */
|
||||||
} ocf_eviction_t;
|
} ocf_eviction_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OCF supported promotion policy types
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
ocf_promotion_nop = 0,
|
||||||
|
/*!< No promotion policy. Cache inserts are not filtered */
|
||||||
|
|
||||||
|
ocf_promotion_nhit,
|
||||||
|
/*!< Line can be inserted after N requests for it */
|
||||||
|
|
||||||
|
ocf_promotion_max,
|
||||||
|
/*!< Stopper of enumerator */
|
||||||
|
|
||||||
|
ocf_promotion_default = ocf_promotion_nop,
|
||||||
|
/*!< Default promotion policy */
|
||||||
|
} ocf_promotion_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OCF supported Write-Back cleaning policies type
|
* OCF supported Write-Back cleaning policies type
|
||||||
*/
|
*/
|
||||||
|
@ -262,6 +262,11 @@ struct ocf_mngt_cache_config {
|
|||||||
*/
|
*/
|
||||||
ocf_eviction_t eviction_policy;
|
ocf_eviction_t eviction_policy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Promotion policy type
|
||||||
|
*/
|
||||||
|
ocf_promotion_t promotion_policy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Cache line size
|
* @brief Cache line size
|
||||||
*/
|
*/
|
||||||
@ -313,6 +318,7 @@ static inline void ocf_mngt_cache_config_set_default(
|
|||||||
cfg->name = NULL;
|
cfg->name = NULL;
|
||||||
cfg->cache_mode = ocf_cache_mode_default;
|
cfg->cache_mode = ocf_cache_mode_default;
|
||||||
cfg->eviction_policy = ocf_eviction_default;
|
cfg->eviction_policy = ocf_eviction_default;
|
||||||
|
cfg->promotion_policy = ocf_promotion_default;
|
||||||
cfg->cache_line_size = ocf_cache_line_size_4;
|
cfg->cache_line_size = ocf_cache_line_size_4;
|
||||||
cfg->metadata_layout = ocf_metadata_layout_default;
|
cfg->metadata_layout = ocf_metadata_layout_default;
|
||||||
cfg->metadata_volatile = false;
|
cfg->metadata_volatile = false;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "../utils/utils_cleaner.h"
|
#include "../utils/utils_cleaner.h"
|
||||||
#include "../metadata/metadata.h"
|
#include "../metadata/metadata.h"
|
||||||
#include "../eviction/eviction.h"
|
#include "../eviction/eviction.h"
|
||||||
|
#include "../promotion/promotion.h"
|
||||||
|
|
||||||
void ocf_engine_error(struct ocf_request *req,
|
void ocf_engine_error(struct ocf_request *req,
|
||||||
bool stop_cache, const char *msg)
|
bool stop_cache, const char *msg)
|
||||||
@ -171,6 +172,7 @@ void ocf_engine_traverse(struct ocf_request *req)
|
|||||||
|
|
||||||
if (entry->status != LOOKUP_HIT) {
|
if (entry->status != LOOKUP_HIT) {
|
||||||
req->info.seq_req = false;
|
req->info.seq_req = false;
|
||||||
|
|
||||||
/* There is miss then lookup for next map entry */
|
/* There is miss then lookup for next map entry */
|
||||||
OCF_DEBUG_PARAM(cache, "Miss, core line = %llu",
|
OCF_DEBUG_PARAM(cache, "Miss, core line = %llu",
|
||||||
entry->core_line);
|
entry->core_line);
|
||||||
@ -249,7 +251,7 @@ static void ocf_engine_map_cache_line(struct ocf_request *req,
|
|||||||
ocf_cleaning_t clean_policy_type;
|
ocf_cleaning_t clean_policy_type;
|
||||||
|
|
||||||
if (cache->device->freelist_part->curr_size == 0) {
|
if (cache->device->freelist_part->curr_size == 0) {
|
||||||
req->info.eviction_error = 1;
|
req->info.mapping_error = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,11 +322,16 @@ void ocf_engine_map(struct ocf_request *req)
|
|||||||
int status = LOOKUP_MAPPED;
|
int status = LOOKUP_MAPPED;
|
||||||
ocf_core_id_t core_id = ocf_core_get_id(req->core);
|
ocf_core_id_t core_id = ocf_core_get_id(req->core);
|
||||||
|
|
||||||
|
if (!ocf_promotion_req_should_promote(cache->promotion_policy, req)) {
|
||||||
|
req->info.mapping_error = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (ocf_engine_unmapped_count(req))
|
if (ocf_engine_unmapped_count(req))
|
||||||
status = space_managment_evict_do(cache, req,
|
status = space_managment_evict_do(cache, req,
|
||||||
ocf_engine_unmapped_count(req));
|
ocf_engine_unmapped_count(req));
|
||||||
|
|
||||||
if (req->info.eviction_error)
|
if (req->info.mapping_error)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ocf_req_clear_info(req);
|
ocf_req_clear_info(req);
|
||||||
@ -342,7 +349,7 @@ void ocf_engine_map(struct ocf_request *req)
|
|||||||
ocf_engine_map_cache_line(req, entry->core_line,
|
ocf_engine_map_cache_line(req, entry->core_line,
|
||||||
entry->hash_key, &entry->coll_idx);
|
entry->hash_key, &entry->coll_idx);
|
||||||
|
|
||||||
if (req->info.eviction_error) {
|
if (req->info.mapping_error) {
|
||||||
/*
|
/*
|
||||||
* Eviction error (mapping error), need to
|
* Eviction error (mapping error), need to
|
||||||
* clean, return and do pass through
|
* clean, return and do pass through
|
||||||
@ -364,6 +371,12 @@ void ocf_engine_map(struct ocf_request *req)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!req->info.mapping_error) {
|
||||||
|
/* request has been inserted into cache - purge it from promotion
|
||||||
|
* policy */
|
||||||
|
ocf_promotion_req_purge(cache->promotion_policy, req);
|
||||||
|
}
|
||||||
|
|
||||||
OCF_DEBUG_PARAM(req->cache, "Sequential - %s", req->info.seq_req ?
|
OCF_DEBUG_PARAM(req->cache, "Sequential - %s", req->info.seq_req ?
|
||||||
"Yes" : "No");
|
"Yes" : "No");
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,8 @@ static void _ocf_discard_core_complete(struct ocf_io *io, int error)
|
|||||||
|
|
||||||
OCF_DEBUG_RQ(req, "Core DISCARD Completion");
|
OCF_DEBUG_RQ(req, "Core DISCARD Completion");
|
||||||
|
|
||||||
|
ocf_promotion_req_purge(req->cache->promotion_policy, req);
|
||||||
|
|
||||||
_ocf_discard_complete_req(req, error);
|
_ocf_discard_complete_req(req, error);
|
||||||
|
|
||||||
ocf_io_put(io);
|
ocf_io_put(io);
|
||||||
|
@ -269,7 +269,7 @@ int ocf_read_generic(struct ocf_request *req)
|
|||||||
*/
|
*/
|
||||||
ocf_engine_map(req);
|
ocf_engine_map(req);
|
||||||
|
|
||||||
if (!req->info.eviction_error) {
|
if (!req->info.mapping_error) {
|
||||||
if (ocf_engine_is_hit(req)) {
|
if (ocf_engine_is_hit(req)) {
|
||||||
/* After mapping turns out there is hit,
|
/* After mapping turns out there is hit,
|
||||||
* so lock OCF request for read access
|
* so lock OCF request for read access
|
||||||
@ -287,7 +287,7 @@ int ocf_read_generic(struct ocf_request *req)
|
|||||||
/*- END Metadata WR access -----------------------------------*/
|
/*- END Metadata WR access -----------------------------------*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!req->info.eviction_error) {
|
if (!req->info.mapping_error) {
|
||||||
if (lock >= 0) {
|
if (lock >= 0) {
|
||||||
if (lock != OCF_LOCK_ACQUIRED) {
|
if (lock != OCF_LOCK_ACQUIRED) {
|
||||||
/* Lock was not acquired, need to wait for resume */
|
/* Lock was not acquired, need to wait for resume */
|
||||||
|
@ -204,7 +204,7 @@ int ocf_write_wb(struct ocf_request *req)
|
|||||||
*/
|
*/
|
||||||
ocf_engine_map(req);
|
ocf_engine_map(req);
|
||||||
|
|
||||||
if (!req->info.eviction_error) {
|
if (!req->info.mapping_error) {
|
||||||
/* Lock request for WRITE access */
|
/* Lock request for WRITE access */
|
||||||
lock = ocf_req_trylock_wr(req);
|
lock = ocf_req_trylock_wr(req);
|
||||||
}
|
}
|
||||||
@ -212,7 +212,7 @@ int ocf_write_wb(struct ocf_request *req)
|
|||||||
OCF_METADATA_UNLOCK_WR(); /*- END Metadata WR access ---------*/
|
OCF_METADATA_UNLOCK_WR(); /*- END Metadata WR access ---------*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!req->info.eviction_error) {
|
if (!req->info.mapping_error) {
|
||||||
if (lock >= 0) {
|
if (lock >= 0) {
|
||||||
if (lock != OCF_LOCK_ACQUIRED) {
|
if (lock != OCF_LOCK_ACQUIRED) {
|
||||||
/* WR lock was not acquired, need to wait for resume */
|
/* WR lock was not acquired, need to wait for resume */
|
||||||
|
@ -197,7 +197,7 @@ int ocf_write_wt(struct ocf_request *req)
|
|||||||
*/
|
*/
|
||||||
ocf_engine_map(req);
|
ocf_engine_map(req);
|
||||||
|
|
||||||
if (!req->info.eviction_error) {
|
if (!req->info.mapping_error) {
|
||||||
/* Lock request for WRITE access */
|
/* Lock request for WRITE access */
|
||||||
lock = ocf_req_trylock_wr(req);
|
lock = ocf_req_trylock_wr(req);
|
||||||
}
|
}
|
||||||
@ -205,7 +205,7 @@ int ocf_write_wt(struct ocf_request *req)
|
|||||||
OCF_METADATA_UNLOCK_WR(); /*- END Metadata WR access ---------*/
|
OCF_METADATA_UNLOCK_WR(); /*- END Metadata WR access ---------*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!req->info.eviction_error) {
|
if (!req->info.mapping_error) {
|
||||||
if (lock >= 0) {
|
if (lock >= 0) {
|
||||||
if (lock != OCF_LOCK_ACQUIRED) {
|
if (lock != OCF_LOCK_ACQUIRED) {
|
||||||
/* WR lock was not acquired, need to wait for resume */
|
/* WR lock was not acquired, need to wait for resume */
|
||||||
|
@ -118,6 +118,6 @@ int space_managment_evict_do(struct ocf_cache *cache,
|
|||||||
if (evict_cline_no <= evicted)
|
if (evict_cline_no <= evicted)
|
||||||
return LOOKUP_MAPPED;
|
return LOOKUP_MAPPED;
|
||||||
|
|
||||||
req->info.eviction_error |= true;
|
req->info.mapping_error |= true;
|
||||||
return LOOKUP_MISS;
|
return LOOKUP_MISS;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
#ifndef __METADATA_SUPERBLOCK_H__
|
#ifndef __METADATA_SUPERBLOCK_H__
|
||||||
#define __METADATA_SUPERBLOCK_H__
|
#define __METADATA_SUPERBLOCK_H__
|
||||||
|
|
||||||
|
#include "../eviction/eviction.h"
|
||||||
|
#include "../promotion/promotion.h"
|
||||||
|
|
||||||
#define CACHE_MAGIC_NUMBER 0x187E1CA6
|
#define CACHE_MAGIC_NUMBER 0x187E1CA6
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,6 +41,7 @@ struct ocf_superblock_config {
|
|||||||
struct cleaning_policy_config cleaning[CLEANING_POLICY_TYPE_MAX];
|
struct cleaning_policy_config cleaning[CLEANING_POLICY_TYPE_MAX];
|
||||||
|
|
||||||
ocf_eviction_t eviction_policy_type;
|
ocf_eviction_t eviction_policy_type;
|
||||||
|
ocf_promotion_t promotion_policy_type;
|
||||||
|
|
||||||
/* Current core sequence number */
|
/* Current core sequence number */
|
||||||
ocf_core_id_t curr_core_seq_no;
|
ocf_core_id_t curr_core_seq_no;
|
||||||
|
@ -91,6 +91,8 @@ struct ocf_cache_mngt_init_params {
|
|||||||
|
|
||||||
ocf_cache_mode_t cache_mode;
|
ocf_cache_mode_t cache_mode;
|
||||||
/*!< cache mode */
|
/*!< cache mode */
|
||||||
|
|
||||||
|
ocf_promotion_t promotion_policy;
|
||||||
} metadata;
|
} metadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -233,10 +235,11 @@ static void __init_partitions_attached(ocf_cache_t cache)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init_cleaning_policy(ocf_cache_t cache)
|
static ocf_error_t __init_cleaning_policy(ocf_cache_t cache)
|
||||||
{
|
{
|
||||||
ocf_cleaning_t cleaning_policy = ocf_cleaning_default;
|
ocf_cleaning_t cleaning_policy = ocf_cleaning_default;
|
||||||
int i;
|
int i;
|
||||||
|
ocf_error_t result = 0;
|
||||||
|
|
||||||
OCF_ASSERT_PLUGGED(cache);
|
OCF_ASSERT_PLUGGED(cache);
|
||||||
|
|
||||||
@ -247,7 +250,9 @@ static void __init_cleaning_policy(ocf_cache_t cache)
|
|||||||
|
|
||||||
cache->conf_meta->cleaning_policy_type = ocf_cleaning_default;
|
cache->conf_meta->cleaning_policy_type = ocf_cleaning_default;
|
||||||
if (cleaning_policy_ops[cleaning_policy].initialize)
|
if (cleaning_policy_ops[cleaning_policy].initialize)
|
||||||
cleaning_policy_ops[cleaning_policy].initialize(cache, 1);
|
result = cleaning_policy_ops[cleaning_policy].initialize(cache, 1);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __deinit_cleaning_policy(ocf_cache_t cache)
|
static void __deinit_cleaning_policy(ocf_cache_t cache)
|
||||||
@ -267,6 +272,19 @@ static void __init_eviction_policy(ocf_cache_t cache,
|
|||||||
cache->conf_meta->eviction_policy_type = eviction;
|
cache->conf_meta->eviction_policy_type = eviction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ocf_error_t __init_promotion_policy(ocf_cache_t cache)
|
||||||
|
{
|
||||||
|
ENV_BUG_ON(cache->promotion_policy);
|
||||||
|
|
||||||
|
return ocf_promotion_init(cache, &cache->promotion_policy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __deinit_promotion_policy(ocf_cache_t cache)
|
||||||
|
{
|
||||||
|
ocf_promotion_deinit(cache->promotion_policy);
|
||||||
|
cache->promotion_policy = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void __init_cores(ocf_cache_t cache)
|
static void __init_cores(ocf_cache_t cache)
|
||||||
{
|
{
|
||||||
/* No core devices yet */
|
/* No core devices yet */
|
||||||
@ -300,17 +318,39 @@ static void __reset_stats(ocf_cache_t cache)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_attached_data_structures(ocf_cache_t cache,
|
static ocf_error_t init_attached_data_structures(ocf_cache_t cache,
|
||||||
ocf_eviction_t eviction_policy)
|
ocf_eviction_t eviction_policy)
|
||||||
{
|
{
|
||||||
|
ocf_error_t result;
|
||||||
|
|
||||||
/* Lock to ensure consistency */
|
/* Lock to ensure consistency */
|
||||||
OCF_METADATA_LOCK_WR();
|
OCF_METADATA_LOCK_WR();
|
||||||
|
|
||||||
__init_hash_table(cache);
|
__init_hash_table(cache);
|
||||||
__init_freelist(cache);
|
__init_freelist(cache);
|
||||||
__init_partitions_attached(cache);
|
__init_partitions_attached(cache);
|
||||||
__init_cleaning_policy(cache);
|
|
||||||
__init_eviction_policy(cache, eviction_policy);
|
result = __init_cleaning_policy(cache);
|
||||||
|
if (result) {
|
||||||
|
ocf_cache_log(cache, log_err,
|
||||||
|
"Cannot initialize cleaning policy\n");
|
||||||
OCF_METADATA_UNLOCK_WR();
|
OCF_METADATA_UNLOCK_WR();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
__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);
|
||||||
|
OCF_METADATA_UNLOCK_WR();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
OCF_METADATA_UNLOCK_WR();
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_attached_data_structures_recovery(ocf_cache_t cache)
|
static void init_attached_data_structures_recovery(ocf_cache_t cache)
|
||||||
@ -468,6 +508,7 @@ void _ocf_mngt_init_instance_load_complete(void *priv, int error)
|
|||||||
struct ocf_cache_attach_context *context = priv;
|
struct ocf_cache_attach_context *context = priv;
|
||||||
ocf_cache_t cache = context->cache;
|
ocf_cache_t cache = context->cache;
|
||||||
ocf_cleaning_t cleaning_policy;
|
ocf_cleaning_t cleaning_policy;
|
||||||
|
ocf_error_t result;
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
ocf_cache_log(cache, log_err,
|
ocf_cache_log(cache, log_err,
|
||||||
@ -480,9 +521,23 @@ void _ocf_mngt_init_instance_load_complete(void *priv, int error)
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (context->metadata.shutdown_status == ocf_metadata_clean_shutdown)
|
if (context->metadata.shutdown_status == ocf_metadata_clean_shutdown)
|
||||||
cleaning_policy_ops[cleaning_policy].initialize(cache, 0);
|
result = cleaning_policy_ops[cleaning_policy].initialize(cache, 0);
|
||||||
else
|
else
|
||||||
cleaning_policy_ops[cleaning_policy].initialize(cache, 1);
|
result = cleaning_policy_ops[cleaning_policy].initialize(cache, 1);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
ocf_cache_log(cache, log_err,
|
||||||
|
"Cannot initialize cleaning policy\n");
|
||||||
|
OCF_PL_FINISH_RET(context->pipeline, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = __init_promotion_policy(cache);
|
||||||
|
if (result) {
|
||||||
|
__deinit_cleaning_policy(cache);
|
||||||
|
ocf_cache_log(cache, log_err,
|
||||||
|
"Cannot initialize promotion policy\n");
|
||||||
|
OCF_PL_FINISH_RET(context->pipeline, result);
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
ocf_pipeline_next(context->pipeline);
|
ocf_pipeline_next(context->pipeline);
|
||||||
@ -1023,6 +1078,7 @@ static void _ocf_mngt_attach_prepare_metadata(ocf_pipeline_t pipeline,
|
|||||||
static void _ocf_mngt_init_instance_init(struct ocf_cache_attach_context *context)
|
static void _ocf_mngt_init_instance_init(struct ocf_cache_attach_context *context)
|
||||||
{
|
{
|
||||||
ocf_cache_t cache = context->cache;
|
ocf_cache_t cache = context->cache;
|
||||||
|
ocf_error_t result;
|
||||||
|
|
||||||
if (!context->metadata.status && !context->cfg.force &&
|
if (!context->metadata.status && !context->cfg.force &&
|
||||||
context->metadata.shutdown_status !=
|
context->metadata.shutdown_status !=
|
||||||
@ -1044,7 +1100,9 @@ static void _ocf_mngt_init_instance_init(struct ocf_cache_attach_context *contex
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init_attached_data_structures(cache, cache->eviction_policy_init);
|
result = init_attached_data_structures(cache, cache->eviction_policy_init);
|
||||||
|
if (result)
|
||||||
|
OCF_PL_FINISH_RET(context->pipeline, result);
|
||||||
|
|
||||||
/* In initial cache state there is no dirty data, so all dirty data is
|
/* In initial cache state there is no dirty data, so all dirty data is
|
||||||
considered to be flushed
|
considered to be flushed
|
||||||
@ -1177,6 +1235,8 @@ static void _ocf_mngt_cache_init(ocf_cache_t cache,
|
|||||||
*/
|
*/
|
||||||
cache->conf_meta->cache_mode = params->metadata.cache_mode;
|
cache->conf_meta->cache_mode = params->metadata.cache_mode;
|
||||||
cache->conf_meta->metadata_layout = params->metadata.layout;
|
cache->conf_meta->metadata_layout = params->metadata.layout;
|
||||||
|
cache->conf_meta->promotion_policy_type =
|
||||||
|
params->metadata.promotion_policy;
|
||||||
|
|
||||||
for (i = 0; i < OCF_IO_CLASS_MAX + 1; ++i) {
|
for (i = 0; i < OCF_IO_CLASS_MAX + 1; ++i) {
|
||||||
cache->user_parts[i].config =
|
cache->user_parts[i].config =
|
||||||
@ -1208,6 +1268,7 @@ static int _ocf_mngt_cache_start(ocf_ctx_t ctx, ocf_cache_t *cache,
|
|||||||
params.metadata.layout = cfg->metadata_layout;
|
params.metadata.layout = cfg->metadata_layout;
|
||||||
params.metadata.line_size = cfg->cache_line_size;
|
params.metadata.line_size = cfg->cache_line_size;
|
||||||
params.metadata_volatile = cfg->metadata_volatile;
|
params.metadata_volatile = cfg->metadata_volatile;
|
||||||
|
params.metadata.promotion_policy = cfg->promotion_policy;
|
||||||
params.locked = cfg->locked;
|
params.locked = cfg->locked;
|
||||||
|
|
||||||
/* Prepare cache */
|
/* Prepare cache */
|
||||||
@ -1766,6 +1827,7 @@ static void _ocf_mngt_cache_unplug(ocf_cache_t cache, bool stop,
|
|||||||
ocf_stop_cleaner(cache);
|
ocf_stop_cleaner(cache);
|
||||||
|
|
||||||
__deinit_cleaning_policy(cache);
|
__deinit_cleaning_policy(cache);
|
||||||
|
__deinit_promotion_policy(cache);
|
||||||
|
|
||||||
if (ocf_mngt_cache_is_dirty(cache)) {
|
if (ocf_mngt_cache_is_dirty(cache)) {
|
||||||
ENV_BUG_ON(!stop);
|
ENV_BUG_ON(!stop);
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "cleaning/cleaning.h"
|
#include "cleaning/cleaning.h"
|
||||||
#include "ocf_logger_priv.h"
|
#include "ocf_logger_priv.h"
|
||||||
#include "ocf/ocf_trace.h"
|
#include "ocf/ocf_trace.h"
|
||||||
|
#include "promotion/promotion.h"
|
||||||
|
|
||||||
#define DIRTY_FLUSHED 1
|
#define DIRTY_FLUSHED 1
|
||||||
#define DIRTY_NOT_FLUSHED 0
|
#define DIRTY_NOT_FLUSHED 0
|
||||||
@ -149,6 +150,7 @@ struct ocf_cache {
|
|||||||
|
|
||||||
struct ocf_cleaner cleaner;
|
struct ocf_cleaner cleaner;
|
||||||
struct ocf_metadata_updater metadata_updater;
|
struct ocf_metadata_updater metadata_updater;
|
||||||
|
ocf_promotion_policy_t promotion_policy;
|
||||||
|
|
||||||
struct ocf_async_lock lock;
|
struct ocf_async_lock lock;
|
||||||
|
|
||||||
|
@ -30,8 +30,8 @@ struct ocf_req_info {
|
|||||||
uint32_t flush_metadata : 1;
|
uint32_t flush_metadata : 1;
|
||||||
/*!< This bit tells if metadata flushing is required */
|
/*!< This bit tells if metadata flushing is required */
|
||||||
|
|
||||||
uint32_t eviction_error : 1;
|
uint32_t mapping_error : 1;
|
||||||
/*!< Eviction error flag */
|
/*!< Core lines in this request were not mapped into cache */
|
||||||
|
|
||||||
uint32_t re_part : 1;
|
uint32_t re_part : 1;
|
||||||
/*!< This bit indicate that in the request some cache lines
|
/*!< This bit indicate that in the request some cache lines
|
||||||
|
36
src/promotion/nhit.c
Normal file
36
src/promotion/nhit.c
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright(c) 2019 Intel Corporation
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../metadata/metadata.h"
|
||||||
|
|
||||||
|
#include "nhit.h"
|
||||||
|
|
||||||
|
ocf_error_t nhit_init(ocf_cache_t cache, ocf_promotion_policy_t policy)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nhit_deinit(ocf_promotion_policy_t policy)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ocf_error_t nhit_set_param(ocf_promotion_policy_t policy, uint8_t param_id,
|
||||||
|
uint64_t param_value)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nhit_req_purge(ocf_promotion_policy_t policy,
|
||||||
|
struct ocf_request *req)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nhit_req_should_promote(ocf_promotion_policy_t policy, struct ocf_request *req)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
26
src/promotion/nhit.h
Normal file
26
src/promotion/nhit.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright(c) 2019 Intel Corporation
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NHIT_PROMOTION_POLICY_H_
|
||||||
|
#define NHIT_PROMOTION_POLICY_H_
|
||||||
|
|
||||||
|
#include "ocf/ocf.h"
|
||||||
|
#include "../ocf_request.h"
|
||||||
|
#include "promotion.h"
|
||||||
|
|
||||||
|
ocf_error_t nhit_init(ocf_cache_t cache, ocf_promotion_policy_t policy);
|
||||||
|
|
||||||
|
void nhit_deinit(ocf_promotion_policy_t policy);
|
||||||
|
|
||||||
|
ocf_error_t nhit_set_param(ocf_promotion_policy_t policy, uint8_t param_id,
|
||||||
|
uint64_t param_value);
|
||||||
|
|
||||||
|
void nhit_req_purge(ocf_promotion_policy_t policy,
|
||||||
|
struct ocf_request *req);
|
||||||
|
|
||||||
|
bool nhit_req_should_promote(ocf_promotion_policy_t policy,
|
||||||
|
struct ocf_request *req);
|
||||||
|
|
||||||
|
#endif /* NHIT_PROMOTION_POLICY_H_ */
|
42
src/promotion/ops.h
Normal file
42
src/promotion/ops.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright(c) 2019 Intel Corporation
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PROMOTION_OPS_H_
|
||||||
|
#define PROMOTION_OPS_H_
|
||||||
|
|
||||||
|
#include "../metadata/metadata.h"
|
||||||
|
#include "promotion.h"
|
||||||
|
|
||||||
|
struct ocf_promotion_policy {
|
||||||
|
ocf_promotion_t type;
|
||||||
|
void *ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct promotion_policy_ops {
|
||||||
|
const char *name;
|
||||||
|
/*!< Promotion policy name */
|
||||||
|
|
||||||
|
ocf_error_t (*init)(ocf_cache_t cache, ocf_promotion_policy_t policy);
|
||||||
|
/*!< Allocate and initialize promotion policy */
|
||||||
|
|
||||||
|
void (*deinit)(ocf_promotion_policy_t policy);
|
||||||
|
/*!< Deinit and free promotion policy */
|
||||||
|
|
||||||
|
ocf_error_t (*set_param)(ocf_promotion_policy_t policy, uint8_t param_id,
|
||||||
|
uint64_t param_value);
|
||||||
|
/*!< Set promotion policy parameter */
|
||||||
|
|
||||||
|
void (*req_purge)(ocf_promotion_policy_t policy,
|
||||||
|
struct ocf_request *req);
|
||||||
|
/*!< Call when request core lines have been inserted or it is
|
||||||
|
* a discard request */
|
||||||
|
|
||||||
|
bool (*req_should_promote)(ocf_promotion_policy_t policy,
|
||||||
|
struct ocf_request *req);
|
||||||
|
/*!< Should request lines be inserted into cache */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* PROMOTION_OPS_H_ */
|
||||||
|
|
99
src/promotion/promotion.c
Normal file
99
src/promotion/promotion.c
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* Copyright(c) 2019 Intel Corporation
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../metadata/metadata.h"
|
||||||
|
|
||||||
|
#include "promotion.h"
|
||||||
|
#include "ops.h"
|
||||||
|
#include "nhit.h"
|
||||||
|
|
||||||
|
struct promotion_policy_ops ocf_promotion_policies[ocf_promotion_max] = {
|
||||||
|
[ocf_promotion_nop] = {
|
||||||
|
.name = "nop",
|
||||||
|
},
|
||||||
|
[ocf_promotion_nhit] = {
|
||||||
|
.name = "nhit",
|
||||||
|
.init = nhit_init,
|
||||||
|
.deinit = nhit_deinit,
|
||||||
|
.set_param = nhit_set_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_policy_t *policy)
|
||||||
|
{
|
||||||
|
ocf_promotion_t type = cache->conf_meta->promotion_policy_type;
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (ocf_promotion_policies[type].init)
|
||||||
|
result = ocf_promotion_policies[type].init(cache, *policy);
|
||||||
|
|
||||||
|
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_param(ocf_promotion_policy_t policy,
|
||||||
|
uint8_t param_id, uint64_t param_value)
|
||||||
|
{
|
||||||
|
ocf_promotion_t type = policy->type;
|
||||||
|
ocf_error_t result = 0;
|
||||||
|
|
||||||
|
ENV_BUG_ON(type >= ocf_promotion_max);
|
||||||
|
|
||||||
|
if (ocf_promotion_policies[type].set_param) {
|
||||||
|
result = ocf_promotion_policies[type].set_param(policy, 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;
|
||||||
|
}
|
||||||
|
|
69
src/promotion/promotion.h
Normal file
69
src/promotion/promotion.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright(c) 2019 Intel Corporation
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PROMOTION_H_
|
||||||
|
#define PROMOTION_H_
|
||||||
|
|
||||||
|
#include "ocf/ocf.h"
|
||||||
|
#include "../ocf_request.h"
|
||||||
|
|
||||||
|
typedef struct ocf_promotion_policy *ocf_promotion_policy_t;
|
||||||
|
/**
|
||||||
|
* @brief Allocate and initialize promotion policy. Should be called after cache
|
||||||
|
* metadata has been allocated and cache->conf_meta->promotion_policy_type has
|
||||||
|
* been set.
|
||||||
|
*
|
||||||
|
* @param[in] cache OCF cache instance
|
||||||
|
* @param[out] param initialized policy handle
|
||||||
|
*
|
||||||
|
* @retval ocf_error_t
|
||||||
|
*/
|
||||||
|
ocf_error_t ocf_promotion_init(ocf_cache_t cache, ocf_promotion_policy_t *policy);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stop, deinitialize and free promotion policy structures.
|
||||||
|
*
|
||||||
|
* @param[in] policy promotion policy handle
|
||||||
|
*
|
||||||
|
* @retval none
|
||||||
|
*/
|
||||||
|
void ocf_promotion_deinit(ocf_promotion_policy_t policy);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set promotion policy parameter
|
||||||
|
*
|
||||||
|
* @param[in] policy promotion policy handle
|
||||||
|
* @param[in] param_id id of parameter to be set
|
||||||
|
* @param[in] param_value value of parameter to be set
|
||||||
|
*
|
||||||
|
* @retval ocf_error_t
|
||||||
|
*/
|
||||||
|
ocf_error_t ocf_promotion_set_param(ocf_promotion_policy_t policy,
|
||||||
|
uint8_t param_id, uint64_t param_value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Update promotion policy after cache lines have been promoted to cache
|
||||||
|
* or discarded from core device
|
||||||
|
*
|
||||||
|
* @param[in] policy promotion policy handle
|
||||||
|
* @param[in] req OCF request to be purged
|
||||||
|
*
|
||||||
|
* @retval none
|
||||||
|
*/
|
||||||
|
void ocf_promotion_req_purge(ocf_promotion_policy_t policy,
|
||||||
|
struct ocf_request *req);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check in promotion policy whether core lines in request can be promoted
|
||||||
|
*
|
||||||
|
* @param[in] policy promotion policy handle
|
||||||
|
* @param[in] req OCF request which is to be promoted
|
||||||
|
*
|
||||||
|
* @retval should core lines belonging to this request be promoted
|
||||||
|
*/
|
||||||
|
bool ocf_promotion_req_should_promote(ocf_promotion_policy_t policy,
|
||||||
|
struct ocf_request *req);
|
||||||
|
|
||||||
|
#endif /* PROMOTION_H_ */
|
@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "utils_cache_line.h"
|
#include "utils_cache_line.h"
|
||||||
|
#include "../promotion/promotion.h"
|
||||||
|
|
||||||
static inline void ocf_cleaning_set_hot_cache_line(struct ocf_cache *cache,
|
static inline void ocf_cleaning_set_hot_cache_line(struct ocf_cache *cache,
|
||||||
ocf_cache_line_t line)
|
ocf_cache_line_t line)
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
#define UTILS_CACHE_LINE_H_
|
#define UTILS_CACHE_LINE_H_
|
||||||
|
|
||||||
#include "../metadata/metadata.h"
|
#include "../metadata/metadata.h"
|
||||||
|
#include "../concurrency/ocf_cache_concurrency.h"
|
||||||
#include "../eviction/eviction.h"
|
#include "../eviction/eviction.h"
|
||||||
#include "../eviction/ops.h"
|
#include "../eviction/ops.h"
|
||||||
#include "../concurrency/ocf_cache_concurrency.h"
|
|
||||||
#include "../engine/cache_engine.h"
|
#include "../engine/cache_engine.h"
|
||||||
#include "../ocf_request.h"
|
#include "../ocf_request.h"
|
||||||
#include "../ocf_def_priv.h"
|
#include "../ocf_def_priv.h"
|
||||||
|
@ -46,6 +46,7 @@ class CacheConfig(Structure):
|
|||||||
("_name", c_char_p),
|
("_name", c_char_p),
|
||||||
("_cache_mode", c_uint32),
|
("_cache_mode", c_uint32),
|
||||||
("_eviction_policy", c_uint32),
|
("_eviction_policy", c_uint32),
|
||||||
|
("_promotion_policy", c_uint32),
|
||||||
("_cache_line_size", c_uint64),
|
("_cache_line_size", c_uint64),
|
||||||
("_metadata_layout", c_uint32),
|
("_metadata_layout", c_uint32),
|
||||||
("_metadata_volatile", c_bool),
|
("_metadata_volatile", c_bool),
|
||||||
@ -92,6 +93,12 @@ class EvictionPolicy(IntEnum):
|
|||||||
DEFAULT = LRU
|
DEFAULT = LRU
|
||||||
|
|
||||||
|
|
||||||
|
class PromotionPolicy(IntEnum):
|
||||||
|
NOP = 0
|
||||||
|
NHIT = 1
|
||||||
|
DEFAULT = NOP
|
||||||
|
|
||||||
|
|
||||||
class CleaningPolicy(IntEnum):
|
class CleaningPolicy(IntEnum):
|
||||||
NOP = 0
|
NOP = 0
|
||||||
ALRU = 1
|
ALRU = 1
|
||||||
@ -131,6 +138,7 @@ class Cache:
|
|||||||
name: str = "",
|
name: str = "",
|
||||||
cache_mode: CacheMode = CacheMode.DEFAULT,
|
cache_mode: CacheMode = CacheMode.DEFAULT,
|
||||||
eviction_policy: EvictionPolicy = EvictionPolicy.DEFAULT,
|
eviction_policy: EvictionPolicy = EvictionPolicy.DEFAULT,
|
||||||
|
promotion_policy: PromotionPolicy = PromotionPolicy.DEFAULT,
|
||||||
cache_line_size: CacheLineSize = CacheLineSize.DEFAULT,
|
cache_line_size: CacheLineSize = CacheLineSize.DEFAULT,
|
||||||
metadata_layout: MetadataLayout = MetadataLayout.DEFAULT,
|
metadata_layout: MetadataLayout = MetadataLayout.DEFAULT,
|
||||||
metadata_volatile: bool = False,
|
metadata_volatile: bool = False,
|
||||||
@ -150,6 +158,7 @@ class Cache:
|
|||||||
_name=name.encode("ascii") if name else None,
|
_name=name.encode("ascii") if name else None,
|
||||||
_cache_mode=cache_mode,
|
_cache_mode=cache_mode,
|
||||||
_eviction_policy=eviction_policy,
|
_eviction_policy=eviction_policy,
|
||||||
|
_promotion_policy=promotion_policy,
|
||||||
_cache_line_size=cache_line_size,
|
_cache_line_size=cache_line_size,
|
||||||
_metadata_layout=metadata_layout,
|
_metadata_layout=metadata_layout,
|
||||||
_metadata_volatile=metadata_volatile,
|
_metadata_volatile=metadata_volatile,
|
||||||
|
Loading…
Reference in New Issue
Block a user