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:
Jan Musial 2019-07-11 12:19:29 +02:00
parent 999f3f7245
commit 917cbd859a
20 changed files with 409 additions and 21 deletions

View File

@ -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
*/ */

View File

@ -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;

View File

@ -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");
} }

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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;
} }

View File

@ -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;

View File

@ -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);
result = __init_cleaning_policy(cache);
if (result) {
ocf_cache_log(cache, log_err,
"Cannot initialize cleaning policy\n");
OCF_METADATA_UNLOCK_WR();
return result;
}
__init_eviction_policy(cache, eviction_policy); __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(); 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);

View File

@ -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;

View File

@ -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
View 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
View 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
View 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
View 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
View 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_ */

View File

@ -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)

View File

@ -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"

View File

@ -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,