diff --git a/inc/ocf_cache.h b/inc/ocf_cache.h
index 4f2b909..5f57db9 100644
--- a/inc/ocf_cache.h
+++ b/inc/ocf_cache.h
@@ -72,9 +72,6 @@ struct ocf_cache_info {
set as a result of reaching IO error threshold */
} fallback_pt;
- ocf_eviction_t eviction_policy;
- /*!< Eviction policy selected */
-
ocf_cleaning_t cleaning_policy;
/*!< Cleaning policy selected */
diff --git a/inc/ocf_def.h b/inc/ocf_def.h
index 09af783..89fb2e0 100644
--- a/inc/ocf_def.h
+++ b/inc/ocf_def.h
@@ -199,20 +199,6 @@ typedef enum {
/*!< Default sequential cutoff policy*/
} ocf_seq_cutoff_policy;
-/**
- * OCF supported eviction policy types
- */
-typedef enum {
- ocf_eviction_lru = 0,
- /*!< Last recently used eviction policy */
-
- ocf_eviction_max,
- /*!< Stopper of enumerator */
-
- ocf_eviction_default = ocf_eviction_lru,
- /*!< Default eviction policy */
-} ocf_eviction_t;
-
/**
* OCF supported promotion policy types
*/
@@ -308,7 +294,7 @@ typedef enum {
/**
* Maximum numbers of IO classes per cache instance
*/
-#define OCF_IO_CLASS_MAX OCF_CONFIG_MAX_IO_CLASSES
+#define OCF_USER_IO_CLASS_MAX OCF_CONFIG_MAX_IO_CLASSES
/**
* Minimum value of a valid IO class ID
*/
@@ -316,11 +302,11 @@ typedef enum {
/**
* Maximum value of a valid IO class ID
*/
-#define OCF_IO_CLASS_ID_MAX (OCF_IO_CLASS_MAX - 1)
+#define OCF_IO_CLASS_ID_MAX (OCF_USER_IO_CLASS_MAX - 1)
/**
* Invalid value of IO class id
*/
-#define OCF_IO_CLASS_INVALID OCF_IO_CLASS_MAX
+#define OCF_IO_CLASS_INVALID OCF_USER_IO_CLASS_MAX
/** Maximum size of the IO class name */
#define OCF_IO_CLASS_NAME_MAX 1024
diff --git a/inc/ocf_io_class.h b/inc/ocf_io_class.h
index 8409f58..6e923fd 100644
--- a/inc/ocf_io_class.h
+++ b/inc/ocf_io_class.h
@@ -44,9 +44,6 @@ struct ocf_io_class_info {
* of ioclass's cachelines are evicted.
*/
- uint8_t eviction_policy_type;
- /*!< The type of eviction policy for given IO class */
-
ocf_cleaning_t cleaning_policy_type;
/*!< The type of cleaning policy for given IO class */
};
diff --git a/inc/ocf_mngt.h b/inc/ocf_mngt.h
index a05f63f..aec6892 100644
--- a/inc/ocf_mngt.h
+++ b/inc/ocf_mngt.h
@@ -246,11 +246,6 @@ struct ocf_mngt_cache_config {
*/
ocf_cache_mode_t cache_mode;
- /**
- * @brief Eviction policy type
- */
- ocf_eviction_t eviction_policy;
-
/**
* @brief Promotion policy type
*/
@@ -307,7 +302,6 @@ static inline void ocf_mngt_cache_config_set_default(
struct ocf_mngt_cache_config *cfg)
{
cfg->cache_mode = ocf_cache_mode_default;
- cfg->eviction_policy = ocf_eviction_default;
cfg->promotion_policy = ocf_promotion_default;
cfg->cache_line_size = ocf_cache_line_size_4;
cfg->metadata_layout = ocf_metadata_layout_default;
@@ -874,7 +868,7 @@ struct ocf_mngt_io_class_config {
};
struct ocf_mngt_io_classes_config {
- struct ocf_mngt_io_class_config config[OCF_IO_CLASS_MAX];
+ struct ocf_mngt_io_class_config config[OCF_USER_IO_CLASS_MAX];
};
/**
diff --git a/src/cleaning/acp.c b/src/cleaning/acp.c
index d48fd97..4cb5900 100644
--- a/src/cleaning/acp.c
+++ b/src/cleaning/acp.c
@@ -654,7 +654,7 @@ void cleaning_policy_acp_purge_block(struct ocf_cache *cache,
int cleaning_policy_acp_purge_range(struct ocf_cache *cache,
int core_id, uint64_t start_byte, uint64_t end_byte)
{
- return ocf_metadata_actor(cache, PARTITION_INVALID,
+ return ocf_metadata_actor(cache, PARTITION_UNSPECIFIED,
core_id, start_byte, end_byte,
cleaning_policy_acp_purge_block);
}
diff --git a/src/cleaning/alru.c b/src/cleaning/alru.c
index 6b6f354..219b6de 100644
--- a/src/cleaning/alru.c
+++ b/src/cleaning/alru.c
@@ -9,7 +9,7 @@
#include "alru.h"
#include "../metadata/metadata.h"
#include "../utils/utils_cleaner.h"
-#include "../utils/utils_part.h"
+#include "../utils/utils_user_part.h"
#include "../utils/utils_realloc.h"
#include "../concurrency/ocf_cache_line_concurrency.h"
#include "../ocf_def_priv.h"
@@ -55,62 +55,33 @@ struct alru_flush_ctx {
struct alru_context {
struct alru_flush_ctx flush_ctx;
- env_spinlock list_lock[OCF_IO_CLASS_MAX];
+ env_spinlock list_lock[OCF_USER_IO_CLASS_MAX];
};
/* -- Start of ALRU functions -- */
-
-/* Sets the given collision_index as the new _head_ of the ALRU list. */
-static inline void update_alru_head(struct ocf_cache *cache,
- int partition_id, unsigned int collision_index)
-{
- struct ocf_user_part *part = &cache->user_parts[partition_id];
-
- part->runtime->cleaning.policy.alru.lru_head = collision_index;
-}
-
-/* Sets the given collision_index as the new _tail_ of the ALRU list. */
-static inline void update_alru_tail(struct ocf_cache *cache,
- int partition_id, unsigned int collision_index)
-{
- struct ocf_user_part *part = &cache->user_parts[partition_id];
-
- part->runtime->cleaning.policy.alru.lru_tail = collision_index;
-}
-
-/* Sets the given collision_index as the new _head_ and _tail_
- * of the ALRU list.
- */
-static inline void update_alru_head_tail(struct ocf_cache *cache,
- int partition_id, unsigned int collision_index)
-{
- update_alru_head(cache, partition_id, collision_index);
- update_alru_tail(cache, partition_id, collision_index);
-}
-
-
/* Adds the given collision_index to the _head_ of the ALRU list */
static void add_alru_head(struct ocf_cache *cache, int partition_id,
unsigned int collision_index)
{
unsigned int curr_head_index;
unsigned int collision_table_entries = cache->device->collision_table_entries;
- struct ocf_user_part *part = &cache->user_parts[partition_id];
+ struct alru_cleaning_policy *part_alru = &cache->user_parts[partition_id]
+ .clean_pol->policy.alru;
struct alru_cleaning_policy_meta *alru;
ENV_BUG_ON(!(collision_index < collision_table_entries));
- ENV_BUG_ON(env_atomic_read(
- &part->runtime->cleaning.policy.alru.size) < 0);
+ ENV_BUG_ON(env_atomic_read(&part_alru->size) < 0);
ENV_WARN_ON(!metadata_test_dirty(cache, collision_index));
ENV_WARN_ON(!metadata_test_valid_any(cache, collision_index));
/* First node to be added/ */
- if (env_atomic_read(&part->runtime->cleaning.policy.alru.size) == 0) {
- update_alru_head_tail(cache, partition_id, collision_index);
+ if (env_atomic_read(&part_alru->size) == 0) {
+ part_alru->lru_head = collision_index;
+ part_alru->lru_tail = collision_index;
alru = &ocf_metadata_get_cleaning_policy(cache,
collision_index)->meta.alru;
@@ -121,7 +92,7 @@ static void add_alru_head(struct ocf_cache *cache, int partition_id,
} else {
/* Not the first node to be added. */
- curr_head_index = part->runtime->cleaning.policy.alru.lru_head;
+ curr_head_index = part_alru->lru_head;
ENV_BUG_ON(!(curr_head_index < collision_table_entries));
@@ -136,10 +107,10 @@ static void add_alru_head(struct ocf_cache *cache, int partition_id,
curr_head_index)->meta.alru;
alru->lru_prev = collision_index;
- update_alru_head(cache, partition_id, collision_index);
+ part_alru->lru_head = collision_index;
}
- env_atomic_inc(&part->runtime->cleaning.policy.alru.size);
+ env_atomic_inc(&part_alru->size);
}
/* Deletes the node with the given collision_index from the ALRU list */
@@ -148,14 +119,13 @@ static void remove_alru_list(struct ocf_cache *cache, int partition_id,
{
uint32_t prev_lru_node, next_lru_node;
uint32_t collision_table_entries = cache->device->collision_table_entries;
- struct ocf_user_part *part = &cache->user_parts[partition_id];
- struct alru_cleaning_policy *cleaning_policy =
- &part->runtime->cleaning.policy.alru;
+ struct alru_cleaning_policy *part_alru = &cache->user_parts[partition_id]
+ .clean_pol->policy.alru;
struct alru_cleaning_policy_meta *alru;
ENV_BUG_ON(!(collision_index < collision_table_entries));
- if (env_atomic_read(&part->runtime->cleaning.policy.alru.size) == 0) {
+ if (env_atomic_read(&part_alru->size) == 0) {
ocf_cache_log(cache, log_err, "ERROR: Attempt to remove item "
"from empty ALRU Cleaning Policy queue!\n");
ENV_BUG();
@@ -170,29 +140,29 @@ static void remove_alru_list(struct ocf_cache *cache, int partition_id,
/* Check if entry is not part of the ALRU list */
if ((next_lru_node == collision_table_entries) &&
(prev_lru_node == collision_table_entries) &&
- (cleaning_policy->lru_head != collision_index) &&
- (cleaning_policy->lru_tail != collision_index)) {
+ (part_alru->lru_head != collision_index) &&
+ (part_alru->lru_tail != collision_index)) {
return;
}
/* Case 0: If we are head AND tail, there is only one node. So unlink
* node and set that there is no node left in the list.
*/
- if (cleaning_policy->lru_head == collision_index &&
- cleaning_policy->lru_tail == collision_index) {
+ if (part_alru->lru_head == collision_index &&
+ part_alru->lru_tail == collision_index) {
alru->lru_next = collision_table_entries;
alru->lru_prev = collision_table_entries;
- update_alru_head_tail(cache, partition_id,
- collision_table_entries);
+ part_alru->lru_head = collision_table_entries;
+ part_alru->lru_tail = collision_table_entries;
}
/* Case 1: else if this collision_index is ALRU head, but not tail,
* update head and return
*/
- else if ((cleaning_policy->lru_tail != collision_index) &&
- (cleaning_policy->lru_head == collision_index)) {
+ else if ((part_alru->lru_tail != collision_index) &&
+ (part_alru->lru_head == collision_index)) {
struct alru_cleaning_policy_meta *next_alru;
ENV_BUG_ON(!(next_lru_node < collision_table_entries));
@@ -200,7 +170,7 @@ static void remove_alru_list(struct ocf_cache *cache, int partition_id,
next_alru = &ocf_metadata_get_cleaning_policy(cache,
next_lru_node)->meta.alru;
- update_alru_head(cache, partition_id, next_lru_node);
+ part_alru->lru_head = next_lru_node;
alru->lru_next = collision_table_entries;
next_alru->lru_prev = collision_table_entries;
@@ -210,8 +180,8 @@ static void remove_alru_list(struct ocf_cache *cache, int partition_id,
/* Case 2: else if this collision_index is ALRU tail, but not head,
* update tail and return
*/
- else if ((cleaning_policy->lru_head != collision_index) &&
- (cleaning_policy->lru_tail == collision_index)) {
+ else if ((part_alru->lru_head != collision_index) &&
+ (part_alru->lru_tail == collision_index)) {
struct alru_cleaning_policy_meta *prev_alru;
ENV_BUG_ON(!(prev_lru_node < collision_table_entries));
@@ -219,7 +189,7 @@ static void remove_alru_list(struct ocf_cache *cache, int partition_id,
prev_alru = &ocf_metadata_get_cleaning_policy(cache,
prev_lru_node)->meta.alru;
- update_alru_tail(cache, partition_id, prev_lru_node);
+ part_alru->lru_tail = prev_lru_node;
alru->lru_prev = collision_table_entries;
prev_alru->lru_next = collision_table_entries;
@@ -249,7 +219,7 @@ static void remove_alru_list(struct ocf_cache *cache, int partition_id,
}
- env_atomic_dec(&part->runtime->cleaning.policy.alru.size);
+ env_atomic_dec(&part_alru->size);
}
static bool is_on_alru_list(struct ocf_cache *cache, int partition_id,
@@ -257,9 +227,8 @@ static bool is_on_alru_list(struct ocf_cache *cache, int partition_id,
{
uint32_t prev_lru_node, next_lru_node;
uint32_t collision_table_entries = cache->device->collision_table_entries;
- struct ocf_user_part *part = &cache->user_parts[partition_id];
- struct alru_cleaning_policy *cleaning_policy =
- &part->runtime->cleaning.policy.alru;
+ struct alru_cleaning_policy *part_alru = &cache->user_parts[partition_id]
+ .clean_pol->policy.alru;
struct alru_cleaning_policy_meta *alru;
ENV_BUG_ON(!(collision_index < collision_table_entries));
@@ -270,8 +239,8 @@ static bool is_on_alru_list(struct ocf_cache *cache, int partition_id,
next_lru_node = alru->lru_next;
prev_lru_node = alru->lru_prev;
- return cleaning_policy->lru_tail == collision_index ||
- cleaning_policy->lru_head == collision_index ||
+ return part_alru->lru_tail == collision_index ||
+ part_alru->lru_head == collision_index ||
next_lru_node != collision_table_entries ||
prev_lru_node != collision_table_entries;
}
@@ -321,13 +290,12 @@ static void __cleaning_policy_alru_purge_cache_block_any(
int cleaning_policy_alru_purge_range(struct ocf_cache *cache, int core_id,
uint64_t start_byte, uint64_t end_byte) {
- struct ocf_user_part *part;
+ struct ocf_user_part *user_part;
ocf_part_id_t part_id;
int ret = 0;
- for_each_part(cache, part, part_id) {
- if (env_atomic_read(&part->runtime->cleaning.
- policy.alru.size) == 0)
+ for_each_user_part(cache, user_part, part_id) {
+ if (env_atomic_read(&user_part->clean_pol->policy.alru.size) == 0)
continue;
ret |= ocf_metadata_actor(cache, part_id,
@@ -344,8 +312,8 @@ void cleaning_policy_alru_set_hot_cache_line(struct ocf_cache *cache,
struct alru_context *ctx = cache->cleaner.cleaning_policy_context;
ocf_part_id_t part_id = ocf_metadata_get_partition_id(cache,
cache_line);
- struct ocf_user_part *part = &cache->user_parts[part_id];
-
+ struct alru_cleaning_policy *part_alru = &cache->user_parts[part_id]
+ .clean_pol->policy.alru;
uint32_t prev_lru_node, next_lru_node;
uint32_t collision_table_entries = cache->device->collision_table_entries;
struct alru_cleaning_policy_meta *alru;
@@ -362,10 +330,8 @@ void cleaning_policy_alru_set_hot_cache_line(struct ocf_cache *cache,
if ((next_lru_node != collision_table_entries) ||
(prev_lru_node != collision_table_entries) ||
- ((part->runtime->cleaning.policy.
- alru.lru_head == cache_line) &&
- (part->runtime->cleaning.policy.
- alru.lru_tail == cache_line)))
+ ((part_alru->lru_head == cache_line) &&
+ (part_alru->lru_tail == cache_line)))
remove_alru_list(cache, part_id, cache_line);
add_alru_head(cache, part_id, cache_line);
@@ -375,19 +341,19 @@ void cleaning_policy_alru_set_hot_cache_line(struct ocf_cache *cache,
static void _alru_rebuild(struct ocf_cache *cache)
{
- struct ocf_user_part *part;
+ struct ocf_user_part *user_part;
+ struct alru_cleaning_policy *part_alru;
ocf_part_id_t part_id;
ocf_core_id_t core_id;
ocf_cache_line_t cline;
uint32_t step = 0;
- for_each_part(cache, part, part_id) {
+ for_each_user_part(cache, user_part, part_id) {
/* ALRU initialization */
- env_atomic_set(&part->runtime->cleaning.policy.alru.size, 0);
- part->runtime->cleaning.policy.alru.lru_head =
- cache->device->collision_table_entries;
- part->runtime->cleaning.policy.alru.lru_tail =
- cache->device->collision_table_entries;
+ part_alru = &user_part->clean_pol->policy.alru;
+ env_atomic_set(&part_alru->size, 0);
+ part_alru->lru_head = cache->device->collision_table_entries;
+ part_alru->lru_tail = cache->device->collision_table_entries;
cache->device->runtime_meta->cleaning_thread_access = 0;
}
@@ -410,15 +376,16 @@ static void _alru_rebuild(struct ocf_cache *cache)
}
static int cleaning_policy_alru_initialize_part(struct ocf_cache *cache,
- struct ocf_user_part *part, int init_metadata)
+ struct ocf_user_part *user_part, int init_metadata)
{
+ struct alru_cleaning_policy *part_alru =
+ &user_part->clean_pol->policy.alru;
+
if (init_metadata) {
/* ALRU initialization */
- env_atomic_set(&part->runtime->cleaning.policy.alru.size, 0);
- part->runtime->cleaning.policy.alru.lru_head =
- cache->device->collision_table_entries;
- part->runtime->cleaning.policy.alru.lru_tail =
- cache->device->collision_table_entries;
+ env_atomic_set(&part_alru->size, 0);
+ part_alru->lru_head = cache->device->collision_table_entries;
+ part_alru->lru_tail = cache->device->collision_table_entries;
}
cache->device->runtime_meta->cleaning_thread_access = 0;
@@ -440,7 +407,7 @@ void cleaning_policy_alru_setup(struct ocf_cache *cache)
int cleaning_policy_alru_initialize(ocf_cache_t cache, int init_metadata)
{
- struct ocf_user_part *part;
+ struct ocf_user_part *user_part;
ocf_part_id_t part_id;
struct alru_context *ctx;
int error = 0;
@@ -452,7 +419,7 @@ int cleaning_policy_alru_initialize(ocf_cache_t cache, int init_metadata)
return -OCF_ERR_NO_MEM;
}
- for (i = 0; i < OCF_IO_CLASS_MAX; i++) {
+ for (i = 0; i < OCF_USER_IO_CLASS_MAX; i++) {
error = env_spinlock_init(&ctx->list_lock[i]);
if (error)
break;
@@ -468,9 +435,9 @@ int cleaning_policy_alru_initialize(ocf_cache_t cache, int init_metadata)
cache->cleaner.cleaning_policy_context = ctx;
- for_each_part(cache, part, part_id) {
+ for_each_user_part(cache, user_part, part_id) {
cleaning_policy_alru_initialize_part(cache,
- part, init_metadata);
+ user_part, init_metadata);
}
if (init_metadata)
@@ -486,7 +453,7 @@ void cleaning_policy_alru_deinitialize(struct ocf_cache *cache)
struct alru_context *alru = cache->cleaner.cleaning_policy_context;
unsigned i;
- for (i = 0; i < OCF_IO_CLASS_MAX; i++)
+ for (i = 0; i < OCF_USER_IO_CLASS_MAX; i++)
env_spinlock_destroy(&alru->list_lock[i]);
env_vfree(cache->cleaner.cleaning_policy_context);
@@ -697,17 +664,17 @@ static int get_data_to_flush(struct alru_context *ctx)
struct alru_cleaning_policy_config *config;
struct alru_cleaning_policy_meta *alru;
ocf_cache_line_t cache_line;
- struct ocf_user_part *part;
+ struct ocf_user_part *user_part;
uint32_t last_access;
int to_flush = 0;
int part_id = OCF_IO_CLASS_ID_MAX;
config = (void *)&cache->conf_meta->cleaning[ocf_cleaning_alru].data;
- for_each_part(cache, part, part_id) {
+ for_each_user_part(cache, user_part, part_id) {
env_spinlock_lock(&ctx->list_lock[part_id]);
- cache_line = part->runtime->cleaning.policy.alru.lru_tail;
+ cache_line = user_part->clean_pol->policy.alru.lru_tail;
last_access = compute_timestamp(config);
diff --git a/src/concurrency/ocf_cache_line_concurrency.c b/src/concurrency/ocf_cache_line_concurrency.c
index ae66a1d..5f31293 100644
--- a/src/concurrency/ocf_cache_line_concurrency.c
+++ b/src/concurrency/ocf_cache_line_concurrency.c
@@ -233,15 +233,6 @@ bool ocf_cache_line_are_waiters(struct ocf_alock *alock,
return !ocf_alock_waitlist_is_empty(alock, line);
}
-bool ocf_cache_line_is_locked_exclusively(struct ocf_cache *cache,
- ocf_cache_line_t line)
-{
- struct ocf_alock *alock =
- ocf_cache_line_concurrency(cache);
-
- return ocf_alock_is_locked_exclusively(alock, line);
-}
-
uint32_t ocf_cache_line_concurrency_suspended_no(struct ocf_alock *alock)
{
return ocf_alock_waitlist_count(alock);
diff --git a/src/concurrency/ocf_cache_line_concurrency.h b/src/concurrency/ocf_cache_line_concurrency.h
index 395b1f4..0200928 100644
--- a/src/concurrency/ocf_cache_line_concurrency.h
+++ b/src/concurrency/ocf_cache_line_concurrency.h
@@ -141,9 +141,6 @@ bool ocf_cache_line_is_used(struct ocf_alock *c,
bool ocf_cache_line_are_waiters(struct ocf_alock *c,
ocf_cache_line_t line);
-bool ocf_cache_line_is_locked_exclusively(struct ocf_cache *cache,
- ocf_cache_line_t line);
-
/**
* @brief un_lock request map info entry from from write or read access.
*
diff --git a/src/concurrency/ocf_metadata_concurrency.c b/src/concurrency/ocf_metadata_concurrency.c
index 200b0b1..953ee9b 100644
--- a/src/concurrency/ocf_metadata_concurrency.c
+++ b/src/concurrency/ocf_metadata_concurrency.c
@@ -14,8 +14,8 @@ int ocf_metadata_concurrency_init(struct ocf_metadata_lock *metadata_lock)
unsigned part_iter;
unsigned global_iter;
- for (evp_iter = 0; evp_iter < OCF_NUM_EVICTION_LISTS; evp_iter++)
- env_rwlock_init(&metadata_lock->eviction[evp_iter]);
+ for (evp_iter = 0; evp_iter < OCF_NUM_LRU_LISTS; evp_iter++)
+ env_rwlock_init(&metadata_lock->lru[evp_iter]);
for (global_iter = 0; global_iter < OCF_NUM_GLOBAL_META_LOCKS;
global_iter++) {
@@ -24,7 +24,7 @@ int ocf_metadata_concurrency_init(struct ocf_metadata_lock *metadata_lock)
goto global_err;
}
- for (part_iter = 0; part_iter < OCF_IO_CLASS_MAX; part_iter++) {
+ for (part_iter = 0; part_iter < OCF_USER_IO_CLASS_MAX; part_iter++) {
err = env_spinlock_init(&metadata_lock->partition[part_iter]);
if (err)
goto partition_err;
@@ -41,7 +41,7 @@ global_err:
env_rwsem_destroy(&metadata_lock->global[global_iter].sem);
while (evp_iter--)
- env_rwlock_destroy(&metadata_lock->eviction[evp_iter]);
+ env_rwlock_destroy(&metadata_lock->lru[evp_iter]);
return err;
}
@@ -50,11 +50,11 @@ void ocf_metadata_concurrency_deinit(struct ocf_metadata_lock *metadata_lock)
{
unsigned i;
- for (i = 0; i < OCF_IO_CLASS_MAX; i++)
+ for (i = 0; i < OCF_USER_IO_CLASS_MAX; i++)
env_spinlock_destroy(&metadata_lock->partition[i]);
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++)
- env_rwlock_destroy(&metadata_lock->eviction[i]);
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++)
+ env_rwlock_destroy(&metadata_lock->lru[i]);
for (i = 0; i < OCF_NUM_GLOBAL_META_LOCKS; i++)
env_rwsem_destroy(&metadata_lock->global[i].sem);
diff --git a/src/concurrency/ocf_metadata_concurrency.h b/src/concurrency/ocf_metadata_concurrency.h
index 266712e..97262d8 100644
--- a/src/concurrency/ocf_metadata_concurrency.h
+++ b/src/concurrency/ocf_metadata_concurrency.h
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#include "../ocf_cache_priv.h"
-#include "../eviction/eviction.h"
+#include "../ocf_space.h"
#include "../ocf_queue_priv.h"
#ifndef __OCF_METADATA_CONCURRENCY_H__
@@ -28,69 +28,69 @@ int ocf_metadata_concurrency_attached_init(
void ocf_metadata_concurrency_attached_deinit(
struct ocf_metadata_lock *metadata_lock);
-static inline void ocf_metadata_eviction_wr_lock(
+static inline void ocf_metadata_lru_wr_lock(
struct ocf_metadata_lock *metadata_lock, unsigned ev_list)
{
- env_rwlock_write_lock(&metadata_lock->eviction[ev_list]);
+ env_rwlock_write_lock(&metadata_lock->lru[ev_list]);
}
-static inline void ocf_metadata_eviction_wr_unlock(
+static inline void ocf_metadata_lru_wr_unlock(
struct ocf_metadata_lock *metadata_lock, unsigned ev_list)
{
- env_rwlock_write_unlock(&metadata_lock->eviction[ev_list]);
+ env_rwlock_write_unlock(&metadata_lock->lru[ev_list]);
}
-static inline void ocf_metadata_eviction_rd_lock(
+static inline void ocf_metadata_lru_rd_lock(
struct ocf_metadata_lock *metadata_lock, unsigned ev_list)
{
- env_rwlock_read_lock(&metadata_lock->eviction[ev_list]);
+ env_rwlock_read_lock(&metadata_lock->lru[ev_list]);
}
-static inline void ocf_metadata_eviction_rd_unlock(
+static inline void ocf_metadata_lru_rd_unlock(
struct ocf_metadata_lock *metadata_lock, unsigned ev_list)
{
- env_rwlock_read_unlock(&metadata_lock->eviction[ev_list]);
+ env_rwlock_read_unlock(&metadata_lock->lru[ev_list]);
}
-static inline void ocf_metadata_eviction_wr_lock_all(
+static inline void ocf_metadata_lru_wr_lock_all(
struct ocf_metadata_lock *metadata_lock)
{
uint32_t i;
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++)
- ocf_metadata_eviction_wr_lock(metadata_lock, i);
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++)
+ ocf_metadata_lru_wr_lock(metadata_lock, i);
}
-static inline void ocf_metadata_eviction_wr_unlock_all(
+static inline void ocf_metadata_lru_wr_unlock_all(
struct ocf_metadata_lock *metadata_lock)
{
uint32_t i;
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++)
- ocf_metadata_eviction_wr_unlock(metadata_lock, i);
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++)
+ ocf_metadata_lru_wr_unlock(metadata_lock, i);
}
-#define OCF_METADATA_EVICTION_WR_LOCK(cline) \
- ocf_metadata_eviction_wr_lock(&cache->metadata.lock, \
- cline % OCF_NUM_EVICTION_LISTS)
+#define OCF_METADATA_LRU_WR_LOCK(cline) \
+ ocf_metadata_lru_wr_lock(&cache->metadata.lock, \
+ cline % OCF_NUM_LRU_LISTS)
-#define OCF_METADATA_EVICTION_WR_UNLOCK(cline) \
- ocf_metadata_eviction_wr_unlock(&cache->metadata.lock, \
- cline % OCF_NUM_EVICTION_LISTS)
+#define OCF_METADATA_LRU_WR_UNLOCK(cline) \
+ ocf_metadata_lru_wr_unlock(&cache->metadata.lock, \
+ cline % OCF_NUM_LRU_LISTS)
-#define OCF_METADATA_EVICTION_RD_LOCK(cline) \
- ocf_metadata_eviction_rd_lock(&cache->metadata.lock, \
- cline % OCF_NUM_EVICTION_LISTS)
+#define OCF_METADATA_LRU_RD_LOCK(cline) \
+ ocf_metadata_lru_rd_lock(&cache->metadata.lock, \
+ cline % OCF_NUM_LRU_LISTS)
-#define OCF_METADATA_EVICTION_RD_UNLOCK(cline) \
- ocf_metadata_eviction_rd_unlock(&cache->metadata.lock, \
- cline % OCF_NUM_EVICTION_LISTS)
+#define OCF_METADATA_LRU_RD_UNLOCK(cline) \
+ ocf_metadata_lru_rd_unlock(&cache->metadata.lock, \
+ cline % OCF_NUM_LRU_LISTS)
-#define OCF_METADATA_EVICTION_WR_LOCK_ALL() \
- ocf_metadata_eviction_wr_lock_all(&cache->metadata.lock)
+#define OCF_METADATA_LRU_WR_LOCK_ALL() \
+ ocf_metadata_lru_wr_lock_all(&cache->metadata.lock)
-#define OCF_METADATA_EVICTION_WR_UNLOCK_ALL() \
- ocf_metadata_eviction_wr_unlock_all(&cache->metadata.lock)
+#define OCF_METADATA_LRU_WR_UNLOCK_ALL() \
+ ocf_metadata_lru_wr_unlock_all(&cache->metadata.lock)
static inline void ocf_metadata_partition_lock(
struct ocf_metadata_lock *metadata_lock,
diff --git a/src/engine/cache_engine.c b/src/engine/cache_engine.c
index 86a65a6..c52ee53 100644
--- a/src/engine/cache_engine.c
+++ b/src/engine/cache_engine.c
@@ -21,11 +21,11 @@
#include "engine_discard.h"
#include "engine_d2c.h"
#include "engine_ops.h"
-#include "../utils/utils_part.h"
+#include "../utils/utils_user_part.h"
#include "../utils/utils_refcnt.h"
#include "../ocf_request.h"
#include "../metadata/metadata.h"
-#include "../eviction/eviction.h"
+#include "../ocf_space.h"
enum ocf_io_if_type {
/* Public OCF IO interfaces to be set by user */
@@ -192,8 +192,8 @@ void ocf_resolve_effective_cache_mode(ocf_cache_t cache,
return;
}
- req->cache_mode = ocf_part_get_cache_mode(cache,
- ocf_part_class2id(cache, req->part_id));
+ req->cache_mode = ocf_user_part_get_cache_mode(cache,
+ ocf_user_part_class2id(cache, req->part_id));
if (!ocf_cache_mode_is_valid(req->cache_mode))
req->cache_mode = cache->conf_meta->cache_mode;
diff --git a/src/engine/cache_engine.h b/src/engine/cache_engine.h
index 5a42a99..91c440b 100644
--- a/src/engine/cache_engine.h
+++ b/src/engine/cache_engine.h
@@ -11,8 +11,7 @@ struct ocf_request;
#define LOOKUP_HIT 5
#define LOOKUP_MISS 6
-#define LOOKUP_INSERTED 8
-#define LOOKUP_REMAPPED 9
+#define LOOKUP_REMAPPED 8
typedef enum {
/* modes inherited from user API */
diff --git a/src/engine/engine_common.c b/src/engine/engine_common.c
index 2e28d6d..8fa878f 100644
--- a/src/engine/engine_common.c
+++ b/src/engine/engine_common.c
@@ -7,16 +7,15 @@
#include "../ocf_priv.h"
#include "../ocf_cache_priv.h"
#include "../ocf_queue_priv.h"
-#include "../ocf_freelist.h"
#include "engine_common.h"
#define OCF_ENGINE_DEBUG_IO_NAME "common"
#include "engine_debug.h"
#include "../utils/utils_cache_line.h"
#include "../ocf_request.h"
#include "../utils/utils_cleaner.h"
-#include "../utils/utils_part.h"
+#include "../utils/utils_user_part.h"
#include "../metadata/metadata.h"
-#include "../eviction/eviction.h"
+#include "../ocf_space.h"
#include "../promotion/promotion.h"
#include "../concurrency/ocf_concurrency.h"
@@ -123,15 +122,6 @@ void ocf_engine_patch_req_info(struct ocf_cache *cache,
req->info.insert_no++;
- if (req->part_id != ocf_metadata_get_partition_id(cache,
- entry->coll_idx)) {
- /*
- * Need to move this cache line into other partition
- */
- entry->re_part = true;
- req->info.re_part_no++;
- }
-
if (idx > 0 && ocf_engine_clines_phys_cont(req, idx - 1))
req->info.seq_no++;
if (idx + 1 < req->core_line_count &&
@@ -152,8 +142,7 @@ static void ocf_engine_update_req_info(struct ocf_cache *cache,
ENV_BUG_ON(entry->status != LOOKUP_HIT &&
entry->status != LOOKUP_MISS &&
- entry->status != LOOKUP_REMAPPED &&
- entry->status != LOOKUP_INSERTED);
+ entry->status != LOOKUP_REMAPPED);
/* Handle return value */
if (entry->status == LOOKUP_HIT) {
@@ -187,10 +176,8 @@ static void ocf_engine_update_req_info(struct ocf_cache *cache,
}
- if (entry->status == LOOKUP_INSERTED ||
- entry->status == LOOKUP_REMAPPED) {
+ if (entry->status == LOOKUP_REMAPPED)
req->info.insert_no++;
- }
/* Check if cache hit is sequential */
if (idx > 0 && ocf_engine_clines_phys_cont(req, idx - 1))
@@ -215,7 +202,7 @@ static void ocf_engine_set_hot(struct ocf_request *req)
if (status == LOOKUP_HIT) {
/* Update eviction (LRU) */
- ocf_eviction_set_hot_cache_line(cache, entry->coll_idx);
+ ocf_lru_hot_cline(cache, entry->coll_idx);
}
}
}
@@ -336,26 +323,6 @@ void ocf_map_cache_line(struct ocf_request *req,
}
-static void ocf_engine_map_cache_line(struct ocf_request *req,
- unsigned int idx)
-{
- struct ocf_cache *cache = req->cache;
- ocf_cache_line_t cache_line;
-
- if (!ocf_freelist_get_cache_line(cache->freelist, &cache_line)) {
- ocf_req_set_mapping_error(req);
- return;
- }
-
- ocf_metadata_add_to_partition(cache, req->part_id, cache_line);
-
- ocf_map_cache_line(req, idx, cache_line);
-
- /* Update LRU:: Move this node to head of lru list. */
- ocf_eviction_init_cache_line(cache, cache_line);
- ocf_eviction_set_hot_cache_line(cache, cache_line);
-}
-
static void ocf_engine_map_hndl_error(struct ocf_cache *cache,
struct ocf_request *req)
{
@@ -370,7 +337,6 @@ static void ocf_engine_map_hndl_error(struct ocf_cache *cache,
case LOOKUP_MISS:
break;
- case LOOKUP_INSERTED:
case LOOKUP_REMAPPED:
OCF_DEBUG_RQ(req, "Canceling cache line %u",
entry->coll_idx);
@@ -395,56 +361,6 @@ static void ocf_engine_map_hndl_error(struct ocf_cache *cache,
}
}
-static void ocf_engine_map(struct ocf_request *req)
-{
- struct ocf_cache *cache = req->cache;
- uint32_t i;
- struct ocf_map_info *entry;
- uint64_t core_line;
- ocf_core_id_t core_id = ocf_core_get_id(req->core);
-
- ocf_req_clear_info(req);
-
- OCF_DEBUG_TRACE(req->cache);
-
- for (i = 0, core_line = req->core_line_first;
- core_line <= req->core_line_last; core_line++, i++) {
- entry = &(req->map[i]);
-
- ocf_engine_lookup_map_entry(cache, entry, core_id, core_line);
-
- /* attempt mapping only if no mapping error previously,
- * otherwise continue the loop anyway to have request fully
- * traversed after map()
- */
- if (entry->status != LOOKUP_HIT &&
- !ocf_req_test_mapping_error(req)) {
- ocf_engine_map_cache_line(req, i);
- if (!ocf_req_test_mapping_error(req))
- entry->status = LOOKUP_INSERTED;
- }
-
- if (entry->status != LOOKUP_MISS)
- ocf_engine_update_req_info(cache, req, i);
-
- OCF_DEBUG_PARAM(req->cache,
- "%s, cache line %u, core line = %llu",
- entry->status == LOOKUP_HIT ? "Hit" :
- entry->status == LOOKUP_MISS : "Miss" :
- "Insert",
- entry->coll_idx, entry->core_line);
- }
-
- if (!ocf_req_test_mapping_error(req)) {
- /* 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",
- ocf_engine_is_sequential(req) ? "Yes" : "No");
-}
-
static void _ocf_engine_clean_end(void *private_data, int error)
{
struct ocf_request *req = private_data;
@@ -469,21 +385,21 @@ static void _ocf_engine_clean_end(void *private_data, int error)
}
}
-static void ocf_engine_evict(struct ocf_request *req)
+static void ocf_engine_remap(struct ocf_request *req)
{
int status;
- status = space_managment_evict_do(req);
+ status = ocf_space_managment_remap_do(req);
if (status == LOOKUP_MISS) {
/* mark error */
ocf_req_set_mapping_error(req);
- /* unlock cachelines locked during eviction */
+ /* unlock cachelines locked during remapping */
ocf_req_unlock(ocf_cache_line_concurrency(req->cache),
req);
/* request cleaning */
- ocf_req_set_clean_eviction(req);
+ ocf_req_set_cleaning_required(req);
/* unmap inserted and replaced cachelines */
ocf_engine_map_hndl_error(req->cache, req);
@@ -495,29 +411,25 @@ static void ocf_engine_evict(struct ocf_request *req)
static int lock_clines(struct ocf_request *req)
{
struct ocf_alock *c = ocf_cache_line_concurrency(req->cache);
- enum ocf_engine_lock_type lock_type =
- req->engine_cbs->get_lock_type(req);
+ int lock_type = OCF_WRITE;
- switch (lock_type) {
- case ocf_engine_lock_write:
- return ocf_req_async_lock_wr(c, req, req->engine_cbs->resume);
- case ocf_engine_lock_read:
- return ocf_req_async_lock_rd(c, req, req->engine_cbs->resume);
- default:
- return OCF_LOCK_ACQUIRED;
- }
+ if (req->rw == OCF_READ && ocf_engine_is_hit(req))
+ lock_type = OCF_READ;
+
+ return lock_type == OCF_WRITE ?
+ ocf_req_async_lock_wr(c, req, req->engine_cbs->resume) :
+ ocf_req_async_lock_rd(c, req, req->engine_cbs->resume);
}
-/* Attempt to map cachelines marked as LOOKUP_MISS by evicting from cache.
+/* Attempt to map cachelines marked as LOOKUP_MISS.
* Caller must assure that request map info is up to date (request
* is traversed).
*/
-static inline int ocf_prepare_clines_evict(struct ocf_request *req)
+static inline void ocf_prepare_clines_miss(struct ocf_request *req)
{
- int lock_status = -OCF_ERR_NO_LOCK;
bool part_has_space;
- part_has_space = ocf_part_has_space(req);
+ part_has_space = ocf_user_part_has_space(req);
if (!part_has_space) {
/* adding more cachelines to target partition would overflow
it - requesting eviction from target partition only */
@@ -527,63 +439,24 @@ static inline int ocf_prepare_clines_evict(struct ocf_request *req)
ocf_req_clear_part_evict(req);
}
- ocf_engine_evict(req);
+ ocf_engine_remap(req);
- if (!ocf_req_test_mapping_error(req)) {
+ if (!ocf_req_test_mapping_error(req))
ocf_promotion_req_purge(req->cache->promotion_policy, req);
- lock_status = lock_clines(req);
- if (lock_status < 0)
- ocf_req_set_mapping_error(req);
- }
-
- return lock_status;
-}
-
-static inline int ocf_prepare_clines_miss(struct ocf_request *req)
-{
- int lock_status = -OCF_ERR_NO_LOCK;
-
- /* requests to disabled partitions go in pass-through */
- if (!ocf_part_is_enabled(&req->cache->user_parts[req->part_id])) {
- ocf_req_set_mapping_error(req);
- return lock_status;
- }
-
- /* NOTE: ocf_part_has_space() below uses potentially stale request
- * statistics (collected before hash bucket lock had been upgraded).
- * It is ok since this check is opportunistic, as partition occupancy
- * is also subject to change. */
- if (!ocf_part_has_space(req)) {
- ocf_engine_lookup(req);
- return ocf_prepare_clines_evict(req);
- }
-
- ocf_engine_map(req);
- if (!ocf_req_test_mapping_error(req)) {
- lock_status = lock_clines(req);
- if (lock_status < 0) {
- /* Mapping succeeded, but we failed to acquire cacheline lock.
- * Don't try to evict, just return error to caller */
- ocf_req_set_mapping_error(req);
- }
- return lock_status;
- }
-
- /* Request mapping failed, but it is fully traversed as a side
- * effect of ocf_engine_map(), so no need to repeat the traversation
- * before eviction.
- * */
- req->info.mapping_error = false;
- return ocf_prepare_clines_evict(req);
}
int ocf_engine_prepare_clines(struct ocf_request *req)
{
- struct ocf_user_part *part = &req->cache->user_parts[req->part_id];
+ struct ocf_user_part *user_part = &req->cache->user_parts[req->part_id];
bool mapped;
bool promote = true;
int lock = -OCF_ERR_NO_LOCK;
- int result;
+
+ /* requests to disabled partitions go in pass-through */
+ if (!ocf_user_part_is_enabled(user_part)) {
+ ocf_req_set_mapping_error(req);
+ return -OCF_ERR_NO_LOCK;
+ }
/* Calculate hashes for hash-bucket locking */
ocf_req_hash(req);
@@ -599,7 +472,10 @@ int ocf_engine_prepare_clines(struct ocf_request *req)
mapped = ocf_engine_is_mapped(req);
if (mapped) {
lock = lock_clines(req);
- ocf_engine_set_hot(req);
+ if (lock < 0)
+ ocf_req_set_mapping_error(req);
+ else
+ ocf_engine_set_hot(req);
ocf_hb_req_prot_unlock_rd(req);
return lock;
}
@@ -615,6 +491,10 @@ int ocf_engine_prepare_clines(struct ocf_request *req)
/* Mapping must be performed holding (at least) hash-bucket write lock */
ocf_hb_req_prot_lock_upgrade(req);
+
+ /* Repeat lookup after upgrading lock */
+ ocf_engine_lookup(req);
+
if (unlikely(ocf_engine_is_mapped(req))) {
lock = lock_clines(req);
ocf_engine_set_hot(req);
@@ -622,17 +502,27 @@ int ocf_engine_prepare_clines(struct ocf_request *req)
return lock;
}
- result = ocf_prepare_clines_miss(req);
+ ocf_prepare_clines_miss(req);
+ if (!ocf_req_test_mapping_error(req)) {
+ lock = lock_clines(req);
+ if (lock < 0) {
+ /* Mapping succeeded, but we failed to acquire cacheline lock.
+ * Don't try to evict, just return error to caller */
+ ocf_req_set_mapping_error(req);
+ }
+ }
+
if (!ocf_req_test_mapping_error(req))
ocf_engine_set_hot(req);
+
ocf_hb_req_prot_unlock_wr(req);
- if (ocf_req_test_clean_eviction(req)) {
- ocf_eviction_flush_dirty(req->cache, part, req->io_queue,
+ if (ocf_req_is_cleaning_required(req)) {
+ ocf_lru_clean(req->cache, user_part, req->io_queue,
128);
}
- return result;
+ return lock;
}
static int _ocf_engine_clean_getter(struct ocf_cache *cache,
diff --git a/src/engine/engine_common.h b/src/engine/engine_common.h
index 353c607..239549b 100644
--- a/src/engine/engine_common.h
+++ b/src/engine/engine_common.h
@@ -210,19 +210,6 @@ void ocf_engine_lookup_map_entry(struct ocf_cache *cache,
struct ocf_map_info *entry, ocf_core_id_t core_id,
uint64_t core_line);
-/**
- * @brief Request cacheline lock type
- */
-enum ocf_engine_lock_type
-{
- /** No lock */
- ocf_engine_lock_none = 0,
- /** Write lock */
- ocf_engine_lock_write,
- /** Read lock */
- ocf_engine_lock_read,
-};
-
/**
* @brief Engine-specific callbacks for common request handling rountine
*
@@ -230,9 +217,6 @@ enum ocf_engine_lock_type
*/
struct ocf_engine_callbacks
{
- /** Specify locking requirements after request is mapped */
- enum ocf_engine_lock_type (*get_lock_type)(struct ocf_request *req);
-
/** Resume handling after acquiring asynchronous lock */
ocf_req_async_lock_cb resume;
};
diff --git a/src/engine/engine_fast.c b/src/engine/engine_fast.c
index ce5a39d..3e7b6d3 100644
--- a/src/engine/engine_fast.c
+++ b/src/engine/engine_fast.c
@@ -10,7 +10,7 @@
#include "engine_pt.h"
#include "engine_wb.h"
#include "../ocf_request.h"
-#include "../utils/utils_part.h"
+#include "../utils/utils_user_part.h"
#include "../utils/utils_io.h"
#include "../concurrency/ocf_concurrency.h"
#include "../metadata/metadata.h"
@@ -77,7 +77,7 @@ static int _ocf_read_fast_do(struct ocf_request *req)
/* Probably some cache lines are assigned into wrong
* partition. Need to move it to new one
*/
- ocf_part_move(req);
+ ocf_user_part_move(req);
ocf_hb_req_prot_unlock_wr(req);
}
@@ -126,7 +126,7 @@ int ocf_read_fast(struct ocf_request *req)
hit = ocf_engine_is_hit(req);
- part_has_space = ocf_part_has_space(req);
+ part_has_space = ocf_user_part_has_space(req);
if (hit && part_has_space) {
ocf_io_start(&req->ioi.io);
@@ -198,7 +198,7 @@ int ocf_write_fast(struct ocf_request *req)
mapped = ocf_engine_is_mapped(req);
- part_has_space = ocf_part_has_space(req);
+ part_has_space = ocf_user_part_has_space(req);
if (mapped && part_has_space) {
ocf_io_start(&req->ioi.io);
diff --git a/src/engine/engine_pt.c b/src/engine/engine_pt.c
index 66322e8..e0465ba 100644
--- a/src/engine/engine_pt.c
+++ b/src/engine/engine_pt.c
@@ -9,7 +9,7 @@
#include "cache_engine.h"
#include "../ocf_request.h"
#include "../utils/utils_io.h"
-#include "../utils/utils_part.h"
+#include "../utils/utils_user_part.h"
#include "../metadata/metadata.h"
#include "../concurrency/ocf_concurrency.h"
@@ -75,7 +75,7 @@ int ocf_read_pt_do(struct ocf_request *req)
/* Probably some cache lines are assigned into wrong
* partition. Need to move it to new one
*/
- ocf_part_move(req);
+ ocf_user_part_move(req);
ocf_hb_req_prot_unlock_wr(req);
}
diff --git a/src/engine/engine_rd.c b/src/engine/engine_rd.c
index 178b4b6..5ce9c68 100644
--- a/src/engine/engine_rd.c
+++ b/src/engine/engine_rd.c
@@ -15,7 +15,7 @@
#include "../utils/utils_io.h"
#include "../ocf_request.h"
#include "../utils/utils_cache_line.h"
-#include "../utils/utils_part.h"
+#include "../utils/utils_user_part.h"
#include "../metadata/metadata.h"
#include "../ocf_def_priv.h"
@@ -182,7 +182,7 @@ static int _ocf_read_generic_do(struct ocf_request *req)
/* Probably some cache lines are assigned into wrong
* partition. Need to move it to new one
*/
- ocf_part_move(req);
+ ocf_user_part_move(req);
ocf_hb_req_prot_unlock_wr(req);
}
@@ -210,17 +210,8 @@ static const struct ocf_io_if _io_if_read_generic_resume = {
.write = _ocf_read_generic_do,
};
-static enum ocf_engine_lock_type ocf_rd_get_lock_type(struct ocf_request *req)
-{
- if (ocf_engine_is_hit(req))
- return ocf_engine_lock_read;
- else
- return ocf_engine_lock_write;
-}
-
static const struct ocf_engine_callbacks _rd_engine_callbacks =
{
- .get_lock_type = ocf_rd_get_lock_type,
.resume = ocf_engine_on_resume,
};
diff --git a/src/engine/engine_wb.c b/src/engine/engine_wb.c
index 6aa43af..7823abb 100644
--- a/src/engine/engine_wb.c
+++ b/src/engine/engine_wb.c
@@ -14,7 +14,7 @@
#include "../utils/utils_io.h"
#include "../utils/utils_cache_line.h"
#include "../utils/utils_request.h"
-#include "../utils/utils_part.h"
+#include "../utils/utils_user_part.h"
#include "../concurrency/ocf_concurrency.h"
#define OCF_ENGINE_DEBUG_IO_NAME "wb"
@@ -135,7 +135,7 @@ static inline void _ocf_write_wb_submit(struct ocf_request *req)
/* Probably some cache lines are assigned into wrong
* partition. Need to move it to new one
*/
- ocf_part_move(req);
+ ocf_user_part_move(req);
ocf_hb_req_prot_unlock_wr(req);
}
@@ -168,14 +168,8 @@ int ocf_write_wb_do(struct ocf_request *req)
return 0;
}
-static enum ocf_engine_lock_type ocf_wb_get_lock_type(struct ocf_request *req)
-{
- return ocf_engine_lock_write;
-}
-
static const struct ocf_engine_callbacks _wb_engine_callbacks =
{
- .get_lock_type = ocf_wb_get_lock_type,
.resume = ocf_engine_on_resume,
};
diff --git a/src/engine/engine_wo.c b/src/engine/engine_wo.c
index 07c1044..0521ad3 100644
--- a/src/engine/engine_wo.c
+++ b/src/engine/engine_wo.c
@@ -12,7 +12,7 @@
#include "../metadata/metadata.h"
#include "../utils/utils_io.h"
#include "../utils/utils_cache_line.h"
-#include "../utils/utils_part.h"
+#include "../utils/utils_user_part.h"
#include "../concurrency/ocf_concurrency.h"
#define OCF_ENGINE_DEBUG_IO_NAME "wo"
diff --git a/src/engine/engine_wt.c b/src/engine/engine_wt.c
index 97ed349..3b0b33f 100644
--- a/src/engine/engine_wt.c
+++ b/src/engine/engine_wt.c
@@ -11,7 +11,7 @@
#include "../ocf_request.h"
#include "../utils/utils_io.h"
#include "../utils/utils_cache_line.h"
-#include "../utils/utils_part.h"
+#include "../utils/utils_user_part.h"
#include "../metadata/metadata.h"
#include "../concurrency/ocf_concurrency.h"
@@ -123,7 +123,7 @@ static void _ocf_write_wt_update_bits(struct ocf_request *req)
/* Probably some cache lines are assigned into wrong
* partition. Need to move it to new one
*/
- ocf_part_move(req);
+ ocf_user_part_move(req);
}
ocf_hb_req_prot_unlock_wr(req);
@@ -155,14 +155,8 @@ static const struct ocf_io_if _io_if_wt_resume = {
.write = _ocf_write_wt_do,
};
-static enum ocf_engine_lock_type ocf_wt_get_lock_type(struct ocf_request *req)
-{
- return ocf_engine_lock_write;
-}
-
static const struct ocf_engine_callbacks _wt_engine_callbacks =
{
- .get_lock_type = ocf_wt_get_lock_type,
.resume = ocf_engine_on_resume,
};
diff --git a/src/eviction/eviction.h b/src/eviction/eviction.h
deleted file mode 100644
index 7ed9d79..0000000
--- a/src/eviction/eviction.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright(c) 2012-2021 Intel Corporation
- * SPDX-License-Identifier: BSD-3-Clause-Clear
- */
-
-#ifndef __LAYER_EVICTION_POLICY_H__
-#define __LAYER_EVICTION_POLICY_H__
-
-#include "ocf/ocf.h"
-#include "lru.h"
-#include "lru_structs.h"
-
-#define OCF_PENDING_EVICTION_LIMIT 512UL
-
-#define OCF_NUM_EVICTION_LISTS 32
-
-struct ocf_user_part;
-struct ocf_request;
-
-struct eviction_policy {
- union {
- struct lru_eviction_policy lru;
- } policy;
-};
-
-/* Eviction policy metadata per cache line */
-union eviction_policy_meta {
- struct lru_eviction_policy_meta lru;
-} __attribute__((packed));
-
-/* the caller must hold the metadata lock for all operations
- *
- * For range operations the caller can:
- * set core_id to -1 to purge the whole cache device
- * set core_id to -2 to purge the whole cache partition
- */
-struct eviction_policy_ops {
- void (*init_cline)(ocf_cache_t cache, ocf_cache_line_t cline);
- void (*rm_cline)(ocf_cache_t cache,
- ocf_cache_line_t cline);
- bool (*can_evict)(ocf_cache_t cache);
- uint32_t (*req_clines)(struct ocf_request *req, struct ocf_user_part *part,
- uint32_t cline_no);
- void (*hot_cline)(ocf_cache_t cache, ocf_cache_line_t cline);
- void (*init_evp)(ocf_cache_t cache, struct ocf_user_part *part);
- void (*dirty_cline)(ocf_cache_t cache,
- struct ocf_user_part *part,
- uint32_t cline_no);
- void (*clean_cline)(ocf_cache_t cache,
- struct ocf_user_part *part,
- uint32_t cline_no);
- void (*flush_dirty)(ocf_cache_t cache, struct ocf_user_part *part,
- ocf_queue_t io_queue, uint32_t count);
- const char *name;
-};
-
-extern struct eviction_policy_ops evict_policy_ops[ocf_eviction_max];
-
-/*
- * Deallocates space according to eviction priorities.
- *
- * @returns:
- * 'LOOKUP_HIT' if evicted enough cachelines to serve @req
- * 'LOOKUP_MISS' otherwise
- */
-int space_managment_evict_do(struct ocf_request *req);
-
-int space_management_free(ocf_cache_t cache, uint32_t count);
-
-#endif
diff --git a/src/eviction/lru.c b/src/eviction/lru.c
deleted file mode 100644
index c6010d0..0000000
--- a/src/eviction/lru.c
+++ /dev/null
@@ -1,790 +0,0 @@
-/*
- * Copyright(c) 2012-2021 Intel Corporation
- * SPDX-License-Identifier: BSD-3-Clause-Clear
- */
-
-#include "eviction.h"
-#include "lru.h"
-#include "ops.h"
-#include "../utils/utils_cleaner.h"
-#include "../utils/utils_cache_line.h"
-#include "../concurrency/ocf_concurrency.h"
-#include "../mngt/ocf_mngt_common.h"
-#include "../engine/engine_zero.h"
-#include "../ocf_cache_priv.h"
-#include "../ocf_request.h"
-#include "../engine/engine_common.h"
-
-#define OCF_EVICTION_MAX_SCAN 1024
-
-static const ocf_cache_line_t end_marker = (ocf_cache_line_t)-1;
-
-/* Adds the given collision_index to the _head_ of the LRU list */
-static void add_lru_head(ocf_cache_t cache,
- struct ocf_lru_list *list,
- unsigned int collision_index)
-
-{
- struct lru_eviction_policy_meta *node;
- unsigned int curr_head_index;
-
- ENV_BUG_ON(collision_index == end_marker);
-
- node = &ocf_metadata_get_eviction_policy(cache, collision_index)->lru;
- node->hot = false;
-
- /* First node to be added/ */
- if (!list->num_nodes) {
- list->head = collision_index;
- list->tail = collision_index;
-
- node->next = end_marker;
- node->prev = end_marker;
-
- list->num_nodes = 1;
- } else {
- struct lru_eviction_policy_meta *curr_head;
-
- /* Not the first node to be added. */
- curr_head_index = list->head;
-
- ENV_BUG_ON(curr_head_index == end_marker);
-
- curr_head = &ocf_metadata_get_eviction_policy(cache,
- curr_head_index)->lru;
-
- node->next = curr_head_index;
- node->prev = end_marker;
- curr_head->prev = collision_index;
- node->hot = true;
- if (!curr_head->hot)
- list->last_hot = collision_index;
- ++list->num_hot;
-
- list->head = collision_index;
-
- ++list->num_nodes;
- }
-}
-
-/* Deletes the node with the given collision_index from the lru list */
-static void remove_lru_list(ocf_cache_t cache,
- struct ocf_lru_list *list,
- unsigned int collision_index)
-{
- int is_head = 0, is_tail = 0;
- uint32_t prev_lru_node, next_lru_node;
- struct lru_eviction_policy_meta *node;
-
- ENV_BUG_ON(collision_index == end_marker);
-
- node = &ocf_metadata_get_eviction_policy(cache, collision_index)->lru;
-
- is_head = (list->head == collision_index);
- is_tail = (list->tail == collision_index);
-
- if (node->hot)
- --list->num_hot;
-
- /* Set prev and next (even if not existent) */
- next_lru_node = node->next;
- prev_lru_node = node->prev;
-
- /* Case 1: If we are head AND tail, there is only one node.
- * So unlink node and set that there is no node left in the list.
- */
- if (is_head && is_tail) {
- node->next = end_marker;
- node->prev = end_marker;
-
- list->head = end_marker;
- list->tail = end_marker;
- list->last_hot = end_marker;
- ENV_BUG_ON(list->num_hot != 0);
- }
-
- /* Case 2: else if this collision_index is LRU head, but not tail,
- * update head and return
- */
- else if (is_head) {
- struct lru_eviction_policy_meta *next_node;
-
- ENV_BUG_ON(next_lru_node == end_marker);
-
- next_node = &ocf_metadata_get_eviction_policy(cache,
- next_lru_node)->lru;
-
- if (list->last_hot == collision_index) {
- ENV_BUG_ON(list->num_hot != 0);
- list->last_hot = end_marker;
- }
-
- list->head = next_lru_node;
-
- node->next = end_marker;
- next_node->prev = end_marker;
- }
-
- /* Case 3: else if this collision_index is LRU tail, but not head,
- * update tail and return
- */
- else if (is_tail) {
- struct lru_eviction_policy_meta *prev_node;
-
- ENV_BUG_ON(prev_lru_node == end_marker);
-
- list->tail = prev_lru_node;
-
- prev_node = &ocf_metadata_get_eviction_policy(cache,
- prev_lru_node)->lru;
-
- node->prev = end_marker;
- prev_node->next = end_marker;
- }
-
- /* Case 4: else this collision_index is a middle node. There is no
- * change to the head and the tail pointers.
- */
- else {
- struct lru_eviction_policy_meta *prev_node;
- struct lru_eviction_policy_meta *next_node;
-
- ENV_BUG_ON(next_lru_node == end_marker);
- ENV_BUG_ON(prev_lru_node == end_marker);
-
- next_node = &ocf_metadata_get_eviction_policy(cache,
- next_lru_node)->lru;
- prev_node = &ocf_metadata_get_eviction_policy(cache,
- prev_lru_node)->lru;
-
- if (list->last_hot == collision_index) {
- ENV_BUG_ON(list->num_hot == 0);
- list->last_hot = prev_lru_node;
- }
-
- /* Update prev and next nodes */
- prev_node->next = node->next;
- next_node->prev = node->prev;
-
- /* Update the given node */
- node->next = end_marker;
- node->prev = end_marker;
- }
-
- node->hot = false;
- --list->num_nodes;
-}
-
-/* Increase / decrease number of hot elements to achieve target count.
- * Asssumes that the list has hot element clustered together at the
- * head of the list.
- */
-static void balance_lru_list(ocf_cache_t cache,
- struct ocf_lru_list *list)
-{
- unsigned target_hot_count = list->num_nodes / OCF_LRU_HOT_RATIO;
- struct lru_eviction_policy_meta *node;
-
- if (target_hot_count == list->num_hot)
- return;
-
- if (list->num_hot == 0) {
- node = &ocf_metadata_get_eviction_policy(cache,
- list->head)->lru;
- list->last_hot = list->head;
- list->num_hot = 1;
- node->hot = 1;
- return;
- }
-
- ENV_BUG_ON(list->last_hot == end_marker);
- node = &ocf_metadata_get_eviction_policy(cache,
- list->last_hot)->lru;
-
- if (target_hot_count > list->num_hot) {
- ++list->num_hot;
- list->last_hot = node->next;
- node = &ocf_metadata_get_eviction_policy(cache,
- node->next)->lru;
- node->hot = true;
- } else {
- if (list->last_hot == list->head) {
- node->hot = false;
- list->num_hot = 0;
- list->last_hot = end_marker;
- } else {
- ENV_BUG_ON(node->prev == end_marker);
- node->hot = false;
- --list->num_hot;
- list->last_hot = node->prev;
- }
- }
-}
-
-
-/*-- End of LRU functions*/
-
-void evp_lru_init_cline(ocf_cache_t cache, ocf_cache_line_t cline)
-{
- struct lru_eviction_policy_meta *node;
-
- node = &ocf_metadata_get_eviction_policy(cache, cline)->lru;
-
- node->hot = false;
- node->prev = end_marker;
- node->next = end_marker;
-}
-
-static struct ocf_lru_list *evp_lru_get_list(struct ocf_user_part *part,
- uint32_t evp, bool clean)
-{
- return clean ? &part->runtime->eviction[evp].policy.lru.clean :
- &part->runtime->eviction[evp].policy.lru.dirty;
-}
-
-static inline struct ocf_lru_list *evp_get_cline_list(ocf_cache_t cache,
- ocf_cache_line_t cline)
-{
- ocf_part_id_t part_id = ocf_metadata_get_partition_id(cache, cline);
- struct ocf_user_part *part = &cache->user_parts[part_id];
- uint32_t ev_list = (cline % OCF_NUM_EVICTION_LISTS);
-
- return evp_lru_get_list(part, ev_list,
- !metadata_test_dirty(cache, cline));
-}
-
-/* the caller must hold the metadata lock */
-void evp_lru_rm_cline(ocf_cache_t cache, ocf_cache_line_t cline)
-{
- struct ocf_lru_list *list;
-
- list = evp_get_cline_list(cache, cline);
- remove_lru_list(cache, list, cline);
- balance_lru_list(cache, list);
-}
-
-static inline void lru_iter_init(struct ocf_lru_iter *iter, ocf_cache_t cache,
- struct ocf_user_part *part, uint32_t start_evp, bool clean,
- bool cl_lock_write, _lru_hash_locked_pfn hash_locked,
- struct ocf_request *req)
-{
- uint32_t i;
-
- /* entire iterator implementation depends on gcc builtins for
- bit operations which works on 64 bit integers at most */
- ENV_BUILD_BUG_ON(OCF_NUM_EVICTION_LISTS > sizeof(iter->evp) * 8);
-
- iter->cache = cache;
- iter->part = part;
- /* set iterator value to start_evp - 1 modulo OCF_NUM_EVICTION_LISTS */
- iter->evp = (start_evp + OCF_NUM_EVICTION_LISTS - 1) % OCF_NUM_EVICTION_LISTS;
- iter->num_avail_evps = OCF_NUM_EVICTION_LISTS;
- iter->next_avail_evp = ((1ULL << OCF_NUM_EVICTION_LISTS) - 1);
- iter->clean = clean;
- iter->cl_lock_write = cl_lock_write;
- iter->hash_locked = hash_locked;
- iter->req = req;
-
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++)
- iter->curr_cline[i] = evp_lru_get_list(part, i, clean)->tail;
-}
-
-static inline void lru_iter_cleaning_init(struct ocf_lru_iter *iter,
- ocf_cache_t cache, struct ocf_user_part *part,
- uint32_t start_evp)
-{
- /* Lock cachelines for read, non-exclusive access */
- lru_iter_init(iter, cache, part, start_evp, false, false,
- NULL, NULL);
-}
-
-static inline void lru_iter_eviction_init(struct ocf_lru_iter *iter,
- ocf_cache_t cache, struct ocf_user_part *part,
- uint32_t start_evp, bool cl_lock_write,
- struct ocf_request *req)
-{
- /* Lock hash buckets for write, cachelines according to user request,
- * however exclusive cacheline access is needed even in case of read
- * access. _evp_lru_evict_hash_locked tells whether given hash bucket
- * is already locked as part of request hash locking (to avoid attempt
- * to acquire the same hash bucket lock twice) */
- lru_iter_init(iter, cache, part, start_evp, true, cl_lock_write,
- ocf_req_hash_in_range, req);
-}
-
-
-static inline uint32_t _lru_next_evp(struct ocf_lru_iter *iter)
-{
- unsigned increment;
-
- increment = __builtin_ffsll(iter->next_avail_evp);
- iter->next_avail_evp = ocf_rotate_right(iter->next_avail_evp,
- increment, OCF_NUM_EVICTION_LISTS);
- iter->evp = (iter->evp + increment) % OCF_NUM_EVICTION_LISTS;
-
- return iter->evp;
-}
-
-
-
-static inline bool _lru_evp_is_empty(struct ocf_lru_iter *iter)
-{
- return !(iter->next_avail_evp & (1ULL << (OCF_NUM_EVICTION_LISTS - 1)));
-}
-
-static inline void _lru_evp_set_empty(struct ocf_lru_iter *iter)
-{
- iter->next_avail_evp &= ~(1ULL << (OCF_NUM_EVICTION_LISTS - 1));
- iter->num_avail_evps--;
-}
-
-static inline bool _lru_evp_all_empty(struct ocf_lru_iter *iter)
-{
- return iter->num_avail_evps == 0;
-}
-
-static bool inline _lru_trylock_cacheline(struct ocf_lru_iter *iter,
- ocf_cache_line_t cline)
-{
- struct ocf_alock *c =
- ocf_cache_line_concurrency(iter->cache);
-
- return iter->cl_lock_write ?
- ocf_cache_line_try_lock_wr(c, cline) :
- ocf_cache_line_try_lock_rd(c, cline);
-}
-
-static void inline _lru_unlock_cacheline(struct ocf_lru_iter *iter,
- ocf_cache_line_t cline)
-{
- struct ocf_alock *c =
- ocf_cache_line_concurrency(iter->cache);
-
- if (iter->cl_lock_write)
- ocf_cache_line_unlock_wr(c, cline);
- else
- ocf_cache_line_unlock_rd(c, cline);
-}
-
-static bool inline _lru_trylock_hash(struct ocf_lru_iter *iter,
- ocf_core_id_t core_id, uint64_t core_line)
-{
- if (iter->hash_locked != NULL && iter->hash_locked(
- iter->req, core_id, core_line)) {
- return true;
- }
-
- return ocf_hb_cline_naked_trylock_wr(
- &iter->cache->metadata.lock,
- core_id, core_line);
-}
-
-static void inline _lru_unlock_hash(struct ocf_lru_iter *iter,
- ocf_core_id_t core_id, uint64_t core_line)
-{
- if (iter->hash_locked != NULL && iter->hash_locked(
- iter->req, core_id, core_line)) {
- return;
- }
-
- ocf_hb_cline_naked_unlock_wr(
- &iter->cache->metadata.lock,
- core_id, core_line);
-}
-
-static bool inline _lru_iter_evition_lock(struct ocf_lru_iter *iter,
- ocf_cache_line_t cache_line,
- ocf_core_id_t *core_id, uint64_t *core_line)
-
-{
- struct ocf_request *req = iter->req;
-
- if (!_lru_trylock_cacheline(iter, cache_line))
- return false;
-
- ocf_metadata_get_core_info(iter->cache, cache_line,
- core_id, core_line);
-
- /* avoid evicting current request target cachelines */
- if (*core_id == ocf_core_get_id(req->core) &&
- *core_line >= req->core_line_first &&
- *core_line <= req->core_line_last) {
- _lru_unlock_cacheline(iter, cache_line);
- return false;
- }
-
- if (!_lru_trylock_hash(iter, *core_id, *core_line)) {
- _lru_unlock_cacheline(iter, cache_line);
- return false;
- }
-
- if (!ocf_cache_line_is_locked_exclusively(iter->cache,
- cache_line)) {
- _lru_unlock_hash(iter, *core_id, *core_line);
- _lru_unlock_cacheline(iter, cache_line);
- return false;
- }
-
- return true;
-}
-
-/* Get next clean cacheline from tail of lru lists. Caller must not hold any
- * eviction list lock. Returned cacheline is read or write locked, depending on
- * iter->write_lock. Returned cacheline has corresponding metadata hash bucket
- * locked. Cacheline is moved to the head of lru list before being returned */
-static inline ocf_cache_line_t lru_iter_eviction_next(struct ocf_lru_iter *iter,
- ocf_core_id_t *core_id, uint64_t *core_line)
-{
- uint32_t curr_evp;
- ocf_cache_line_t cline;
- ocf_cache_t cache = iter->cache;
- struct ocf_user_part *part = iter->part;
- struct ocf_lru_list *list;
-
- do {
- curr_evp = _lru_next_evp(iter);
-
- ocf_metadata_eviction_wr_lock(&cache->metadata.lock, curr_evp);
-
- list = evp_lru_get_list(part, curr_evp, iter->clean);
-
- cline = list->tail;
- while (cline != end_marker && !_lru_iter_evition_lock(iter,
- cline, core_id, core_line)) {
- cline = ocf_metadata_get_eviction_policy(
- iter->cache, cline)->lru.prev;
- }
-
- if (cline != end_marker) {
- remove_lru_list(cache, list, cline);
- add_lru_head(cache, list, cline);
- balance_lru_list(cache, list);
- }
-
- ocf_metadata_eviction_wr_unlock(&cache->metadata.lock, curr_evp);
-
- if (cline == end_marker && !_lru_evp_is_empty(iter)) {
- /* mark list as empty */
- _lru_evp_set_empty(iter);
- }
- } while (cline == end_marker && !_lru_evp_all_empty(iter));
-
- return cline;
-}
-
-/* Get next dirty cacheline from tail of lru lists. Caller must hold all
- * eviction list locks during entire iteration proces. Returned cacheline
- * is read or write locked, depending on iter->write_lock */
-static inline ocf_cache_line_t lru_iter_cleaning_next(struct ocf_lru_iter *iter)
-{
- uint32_t curr_evp;
- ocf_cache_line_t cline;
-
- do {
- curr_evp = _lru_next_evp(iter);
- cline = iter->curr_cline[curr_evp];
-
- while (cline != end_marker && !_lru_trylock_cacheline(iter,
- cline)) {
- cline = ocf_metadata_get_eviction_policy(
- iter->cache, cline)->lru.prev;
- }
- if (cline != end_marker) {
- iter->curr_cline[curr_evp] =
- ocf_metadata_get_eviction_policy(
- iter->cache , cline)->lru.prev;
- }
-
- if (cline == end_marker && !_lru_evp_is_empty(iter)) {
- /* mark list as empty */
- _lru_evp_set_empty(iter);
- }
- } while (cline == end_marker && !_lru_evp_all_empty(iter));
-
- return cline;
-}
-
-static void evp_lru_clean_end(void *private_data, int error)
-{
- struct ocf_part_cleaning_ctx *ctx = private_data;
- unsigned i;
-
- for (i = 0; i < OCF_EVICTION_CLEAN_SIZE; i++) {
- if (ctx->cline[i] != end_marker)
- ocf_cache_line_unlock_rd(ctx->cache->device->concurrency
- .cache_line, ctx->cline[i]);
- }
-
- ocf_refcnt_dec(&ctx->counter);
-}
-
-static int evp_lru_clean_get(ocf_cache_t cache, void *getter_context,
- uint32_t idx, ocf_cache_line_t *line)
-{
- struct ocf_part_cleaning_ctx *ctx = getter_context;
-
- if (ctx->cline[idx] == end_marker)
- return -1;
-
- *line = ctx->cline[idx];
-
- return 0;
-}
-
-void evp_lru_clean(ocf_cache_t cache, struct ocf_user_part *part,
- ocf_queue_t io_queue, uint32_t count)
-{
- struct ocf_part_cleaning_ctx *ctx = &part->cleaning;
- struct ocf_cleaner_attribs attribs = {
- .lock_cacheline = false,
- .lock_metadata = true,
- .do_sort = true,
-
- .cmpl_context = &part->cleaning,
- .cmpl_fn = evp_lru_clean_end,
-
- .getter = evp_lru_clean_get,
- .getter_context = &part->cleaning,
-
- .count = min(count, OCF_EVICTION_CLEAN_SIZE),
-
- .io_queue = io_queue
- };
- ocf_cache_line_t *cline = part->cleaning.cline;
- struct ocf_lru_iter iter;
- unsigned evp;
- int cnt;
- unsigned i;
- unsigned lock_idx;
-
- if (ocf_mngt_cache_is_locked(cache))
- return;
- cnt = ocf_refcnt_inc(&ctx->counter);
- if (!cnt) {
- /* cleaner disabled by management operation */
- return;
- }
-
- if (cnt > 1) {
- /* cleaning already running for this partition */
- ocf_refcnt_dec(&ctx->counter);
- return;
- }
-
- part->cleaning.cache = cache;
- evp = io_queue->eviction_idx++ % OCF_NUM_EVICTION_LISTS;
-
- lock_idx = ocf_metadata_concurrency_next_idx(io_queue);
- ocf_metadata_start_shared_access(&cache->metadata.lock, lock_idx);
-
- OCF_METADATA_EVICTION_WR_LOCK_ALL();
-
- lru_iter_cleaning_init(&iter, cache, part, evp);
- i = 0;
- while (i < OCF_EVICTION_CLEAN_SIZE) {
- cline[i] = lru_iter_cleaning_next(&iter);
- if (cline[i] == end_marker)
- break;
- i++;
- }
- while (i < OCF_EVICTION_CLEAN_SIZE)
- cline[i++] = end_marker;
-
- OCF_METADATA_EVICTION_WR_UNLOCK_ALL();
-
- ocf_metadata_end_shared_access(&cache->metadata.lock, lock_idx);
-
- ocf_cleaner_fire(cache, &attribs);
-}
-
-bool evp_lru_can_evict(ocf_cache_t cache)
-{
- if (env_atomic_read(&cache->pending_eviction_clines) >=
- OCF_PENDING_EVICTION_LIMIT) {
- return false;
- }
-
- return true;
-}
-
-/* the caller must hold the metadata lock */
-uint32_t evp_lru_req_clines(struct ocf_request *req,
- struct ocf_user_part *part, uint32_t cline_no)
-{
- struct ocf_alock* alock;
- struct ocf_lru_iter iter;
- uint32_t i;
- ocf_cache_line_t cline;
- uint64_t core_line;
- ocf_core_id_t core_id;
- ocf_core_t core;
- ocf_cache_t cache = req->cache;
- bool cl_write_lock =
- (req->engine_cbs->get_lock_type(req) == ocf_engine_lock_write);
- unsigned evp;
- unsigned req_idx = 0;
-
- if (cline_no == 0)
- return 0;
-
- if (unlikely(ocf_engine_unmapped_count(req) < cline_no)) {
- ocf_cache_log(req->cache, log_err, "Not enough space in"
- "request: unmapped %u, requested %u",
- ocf_engine_unmapped_count(req),
- cline_no);
- ENV_BUG();
- }
-
- evp = req->io_queue->eviction_idx++ % OCF_NUM_EVICTION_LISTS;
-
- lru_iter_eviction_init(&iter, cache, part, evp, cl_write_lock, req);
-
- i = 0;
- while (i < cline_no) {
- if (!evp_lru_can_evict(cache))
- break;
-
- cline = lru_iter_eviction_next(&iter, &core_id, &core_line);
-
- if (cline == end_marker)
- break;
-
- ENV_BUG_ON(metadata_test_dirty(cache, cline));
-
- /* TODO: if atomic mode is restored, need to zero metadata
- * before proceeding with cleaning (see version <= 20.12) */
-
- /* find next unmapped cacheline in request */
- while (req_idx + 1 < req->core_line_count &&
- req->map[req_idx].status != LOOKUP_MISS) {
- req_idx++;
- }
-
- ENV_BUG_ON(req->map[req_idx].status != LOOKUP_MISS);
-
- ocf_metadata_start_collision_shared_access(
- cache, cline);
- metadata_clear_valid_sec(cache, cline, 0, ocf_line_end_sector(cache));
- ocf_metadata_remove_from_collision(cache, cline, part->id);
- ocf_metadata_end_collision_shared_access(
- cache, cline);
-
- core = ocf_cache_get_core(cache, core_id);
- env_atomic_dec(&core->runtime_meta->cached_clines);
- env_atomic_dec(&core->runtime_meta->
- part_counters[part->id].cached_clines);
-
- _lru_unlock_hash(&iter, core_id, core_line);
-
- ocf_map_cache_line(req, req_idx, cline);
-
- req->map[req_idx].status = LOOKUP_REMAPPED;
- ocf_engine_patch_req_info(cache, req, req_idx);
-
- alock = ocf_cache_line_concurrency(iter.cache);
-
- ocf_alock_mark_index_locked(alock, req, req_idx, true);
- req->alock_rw = cl_write_lock ? OCF_WRITE : OCF_READ;
-
- ++req_idx;
- ++i;
- /* Number of cachelines to evict have to match space in the request */
- ENV_BUG_ON(req_idx == req->core_line_count && i != cline_no );
- }
-
- return i;
-}
-
-/* the caller must hold the metadata lock */
-void evp_lru_hot_cline(ocf_cache_t cache, ocf_cache_line_t cline)
-{
- struct lru_eviction_policy_meta *node;
- struct ocf_lru_list *list;
- bool hot;
-
- node = &ocf_metadata_get_eviction_policy(cache, cline)->lru;
-
- OCF_METADATA_EVICTION_RD_LOCK(cline);
- hot = node->hot;
- OCF_METADATA_EVICTION_RD_UNLOCK(cline);
-
- if (hot)
- return;
-
- list = evp_get_cline_list(cache, cline);
-
- OCF_METADATA_EVICTION_WR_LOCK(cline);
-
- if (node->next != end_marker ||
- node->prev != end_marker ||
- list->head == cline || list->tail == cline) {
- remove_lru_list(cache, list, cline);
- }
-
- /* Update LRU */
- add_lru_head(cache, list, cline);
- balance_lru_list(cache, list);
-
- OCF_METADATA_EVICTION_WR_UNLOCK(cline);
-}
-
-static inline void _lru_init(struct ocf_lru_list *list)
-{
- list->num_nodes = 0;
- list->head = end_marker;
- list->tail = end_marker;
- list->num_hot = 0;
- list->last_hot = end_marker;
-}
-
-void evp_lru_init_evp(ocf_cache_t cache, struct ocf_user_part *part)
-{
- struct ocf_lru_list *clean_list;
- struct ocf_lru_list *dirty_list;
- uint32_t i;
-
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
- clean_list = evp_lru_get_list(part, i, true);
- dirty_list = evp_lru_get_list(part, i, false);
-
- _lru_init(clean_list);
- _lru_init(dirty_list);
- }
-}
-
-void evp_lru_clean_cline(ocf_cache_t cache, struct ocf_user_part *part,
- uint32_t cline)
-{
- uint32_t ev_list = (cline % OCF_NUM_EVICTION_LISTS);
- struct ocf_lru_list *clean_list;
- struct ocf_lru_list *dirty_list;
-
- clean_list = evp_lru_get_list(part, ev_list, true);
- dirty_list = evp_lru_get_list(part, ev_list, false);
-
- OCF_METADATA_EVICTION_WR_LOCK(cline);
- remove_lru_list(cache, dirty_list, cline);
- balance_lru_list(cache, dirty_list);
- add_lru_head(cache, clean_list, cline);
- balance_lru_list(cache, clean_list);
- OCF_METADATA_EVICTION_WR_UNLOCK(cline);
-}
-
-void evp_lru_dirty_cline(ocf_cache_t cache, struct ocf_user_part *part,
- uint32_t cline)
-{
- uint32_t ev_list = (cline % OCF_NUM_EVICTION_LISTS);
- struct ocf_lru_list *clean_list;
- struct ocf_lru_list *dirty_list;
-
- clean_list = evp_lru_get_list(part, ev_list, true);
- dirty_list = evp_lru_get_list(part, ev_list, false);
-
- OCF_METADATA_EVICTION_WR_LOCK(cline);
- remove_lru_list(cache, clean_list, cline);
- balance_lru_list(cache, clean_list);
- add_lru_head(cache, dirty_list, cline);
- balance_lru_list(cache, dirty_list);
- OCF_METADATA_EVICTION_WR_UNLOCK(cline);
-}
-
diff --git a/src/eviction/lru.h b/src/eviction/lru.h
deleted file mode 100644
index 22fae14..0000000
--- a/src/eviction/lru.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright(c) 2012-2021 Intel Corporation
- * SPDX-License-Identifier: BSD-3-Clause-Clear
- */
-#ifndef __EVICTION_LRU_H__
-#define __EVICTION_LRU_H__
-
-#include "eviction.h"
-#include "lru_structs.h"
-
-struct ocf_user_part;
-struct ocf_request;
-
-void evp_lru_init_cline(struct ocf_cache *cache, ocf_cache_line_t cline);
-void evp_lru_rm_cline(struct ocf_cache *cache, ocf_cache_line_t cline);
-bool evp_lru_can_evict(struct ocf_cache *cache);
-uint32_t evp_lru_req_clines(struct ocf_request *req,
- struct ocf_user_part *part, uint32_t cline_no);
-void evp_lru_hot_cline(struct ocf_cache *cache, ocf_cache_line_t cline);
-void evp_lru_init_evp(struct ocf_cache *cache, struct ocf_user_part *part);
-void evp_lru_dirty_cline(struct ocf_cache *cache, struct ocf_user_part *part,
- uint32_t cline);
-void evp_lru_clean_cline(struct ocf_cache *cache, struct ocf_user_part *part,
- uint32_t cline);
-void evp_lru_clean(ocf_cache_t cache, struct ocf_user_part *part,
- ocf_queue_t io_queue, uint32_t count);
-#endif
diff --git a/src/eviction/ops.h b/src/eviction/ops.h
deleted file mode 100644
index 9a8408a..0000000
--- a/src/eviction/ops.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright(c) 2012-2021 Intel Corporation
- * SPDX-License-Identifier: BSD-3-Clause-Clear
- */
-
-#ifndef LAYER_EVICTION_POLICY_OPS_H_
-#define LAYER_EVICTION_POLICY_OPS_H_
-
-#include "eviction.h"
-#include "../metadata/metadata.h"
-#include "../concurrency/ocf_metadata_concurrency.h"
-
-/**
- * @brief Initialize cache line before adding it into eviction
- *
- * @note This operation is called under WR metadata lock
- */
-static inline void ocf_eviction_init_cache_line(struct ocf_cache *cache,
- ocf_cache_line_t line)
-{
- uint8_t type;
-
- type = cache->conf_meta->eviction_policy_type;
-
- ENV_BUG_ON(type >= ocf_eviction_max);
-
- if (likely(evict_policy_ops[type].init_cline))
- evict_policy_ops[type].init_cline(cache, line);
-}
-
-static inline void ocf_eviction_purge_cache_line(
- struct ocf_cache *cache, ocf_cache_line_t line)
-{
- uint8_t type = cache->conf_meta->eviction_policy_type;
-
- ENV_BUG_ON(type >= ocf_eviction_max);
-
- if (likely(evict_policy_ops[type].rm_cline)) {
- OCF_METADATA_EVICTION_WR_LOCK(line);
- evict_policy_ops[type].rm_cline(cache, line);
- OCF_METADATA_EVICTION_WR_UNLOCK(line);
- }
-}
-
-static inline bool ocf_eviction_can_evict(struct ocf_cache *cache)
-{
- uint8_t type = cache->conf_meta->eviction_policy_type;
-
- if (likely(evict_policy_ops[type].can_evict))
- return evict_policy_ops[type].can_evict(cache);
-
- return true;
-}
-
-static inline uint32_t ocf_eviction_need_space(ocf_cache_t cache,
- struct ocf_request *req, struct ocf_user_part *part,
- uint32_t clines)
-{
- uint8_t type;
- uint32_t result = 0;
-
- type = cache->conf_meta->eviction_policy_type;
-
- ENV_BUG_ON(type >= ocf_eviction_max);
-
- if (likely(evict_policy_ops[type].req_clines)) {
- result = evict_policy_ops[type].req_clines(req,
- part, clines);
- }
-
- return result;
-}
-
-static inline void ocf_eviction_set_hot_cache_line(
- struct ocf_cache *cache, ocf_cache_line_t line)
-{
- uint8_t type = cache->conf_meta->eviction_policy_type;
-
- ENV_BUG_ON(type >= ocf_eviction_max);
-
- if (likely(evict_policy_ops[type].hot_cline)) {
- evict_policy_ops[type].hot_cline(cache, line);
- }
-}
-
-static inline void ocf_eviction_initialize(struct ocf_cache *cache,
- struct ocf_user_part *part)
-{
- uint8_t type = cache->conf_meta->eviction_policy_type;
-
- ENV_BUG_ON(type >= ocf_eviction_max);
-
- if (likely(evict_policy_ops[type].init_evp)) {
- OCF_METADATA_EVICTION_WR_LOCK_ALL();
- evict_policy_ops[type].init_evp(cache, part);
- OCF_METADATA_EVICTION_WR_UNLOCK_ALL();
- }
-}
-
-static inline void ocf_eviction_flush_dirty(ocf_cache_t cache,
- struct ocf_user_part *part, ocf_queue_t io_queue,
- uint32_t count)
-{
- uint8_t type = cache->conf_meta->eviction_policy_type;
-
- ENV_BUG_ON(type >= ocf_eviction_max);
-
- if (likely(evict_policy_ops[type].flush_dirty)) {
- evict_policy_ops[type].flush_dirty(cache, part, io_queue,
- count);
- }
-}
-
-#endif /* LAYER_EVICTION_POLICY_OPS_H_ */
diff --git a/src/metadata/metadata.c b/src/metadata/metadata.c
index 6501006..b3f501d 100644
--- a/src/metadata/metadata.c
+++ b/src/metadata/metadata.c
@@ -14,7 +14,6 @@
#include "metadata_segment.h"
#include "../concurrency/ocf_concurrency.h"
#include "../ocf_def_priv.h"
-#include "../ocf_freelist.h"
#include "../ocf_priv.h"
#include "../utils/utils_cache_line.h"
#include "../utils/utils_io.h"
@@ -36,6 +35,11 @@
#define OCF_METADATA_HASH_DIFF_MAX 1000
+struct ocf_part_runtime_meta {
+ struct ocf_part_runtime runtime;
+ struct cleaning_policy clean_pol;
+};
+
enum {
ocf_metadata_status_type_valid = 0,
ocf_metadata_status_type_dirty,
@@ -67,7 +71,7 @@ static ocf_cache_line_t ocf_metadata_get_entries(
switch (type) {
case metadata_segment_collision:
case metadata_segment_cleaning:
- case metadata_segment_eviction:
+ case metadata_segment_lru:
case metadata_segment_list_info:
return cache_lines;
@@ -86,10 +90,10 @@ static ocf_cache_line_t ocf_metadata_get_entries(
return 32;
case metadata_segment_part_config:
- return OCF_IO_CLASS_MAX + 1;
+ return OCF_USER_IO_CLASS_MAX + 1;
case metadata_segment_part_runtime:
- return OCF_IO_CLASS_MAX + 1;
+ return OCF_NUM_PARTITIONS;
case metadata_segment_core_config:
return OCF_CORE_MAX;
@@ -120,8 +124,8 @@ static int64_t ocf_metadata_get_element_size(
ENV_BUG_ON(type >= metadata_segment_variable_size_start && !settings);
switch (type) {
- case metadata_segment_eviction:
- size = sizeof(union eviction_policy_meta);
+ case metadata_segment_lru:
+ size = sizeof(struct ocf_lru_meta);
break;
case metadata_segment_cleaning:
@@ -154,7 +158,7 @@ static int64_t ocf_metadata_get_element_size(
break;
case metadata_segment_part_runtime:
- size = sizeof(struct ocf_user_part_runtime);
+ size = sizeof(struct ocf_part_runtime_meta);
break;
case metadata_segment_hash:
@@ -324,7 +328,7 @@ const char * const ocf_metadata_segment_names[] = {
[metadata_segment_part_config] = "Part config",
[metadata_segment_part_runtime] = "Part runtime",
[metadata_segment_cleaning] = "Cleaning",
- [metadata_segment_eviction] = "Eviction",
+ [metadata_segment_lru] = "LRU list",
[metadata_segment_collision] = "Collision",
[metadata_segment_list_info] = "List info",
[metadata_segment_hash] = "Hash",
@@ -515,7 +519,7 @@ static int ocf_metadata_init_fixed_size(struct ocf_cache *cache,
struct ocf_core_meta_config *core_meta_config;
struct ocf_core_meta_runtime *core_meta_runtime;
struct ocf_user_part_config *part_config;
- struct ocf_user_part_runtime *part_runtime;
+ struct ocf_part_runtime_meta *part_runtime_meta;
struct ocf_metadata_segment *superblock;
ocf_core_t core;
ocf_core_id_t core_id;
@@ -565,13 +569,16 @@ static int ocf_metadata_init_fixed_size(struct ocf_cache *cache,
/* Set partition metadata */
part_config = METADATA_MEM_POOL(ctrl, metadata_segment_part_config);
- part_runtime = METADATA_MEM_POOL(ctrl, metadata_segment_part_runtime);
+ part_runtime_meta = METADATA_MEM_POOL(ctrl,
+ metadata_segment_part_runtime);
- for (i = 0; i < OCF_IO_CLASS_MAX + 1; i++) {
+ for (i = 0; i < OCF_USER_IO_CLASS_MAX + 1; i++) {
cache->user_parts[i].config = &part_config[i];
- cache->user_parts[i].runtime = &part_runtime[i];
- cache->user_parts[i].id = i;
+ cache->user_parts[i].clean_pol = &part_runtime_meta[i].clean_pol;
+ cache->user_parts[i].part.runtime =
+ &part_runtime_meta[i].runtime;
}
+ cache->free.runtime= &part_runtime_meta[PARTITION_FREELIST].runtime;
/* Set core metadata */
core_meta_config = METADATA_MEM_POOL(ctrl,
@@ -948,7 +955,7 @@ struct ocf_pipeline_arg ocf_metadata_flush_all_args[] = {
OCF_PL_ARG_INT(metadata_segment_part_runtime),
OCF_PL_ARG_INT(metadata_segment_core_runtime),
OCF_PL_ARG_INT(metadata_segment_cleaning),
- OCF_PL_ARG_INT(metadata_segment_eviction),
+ OCF_PL_ARG_INT(metadata_segment_lru),
OCF_PL_ARG_INT(metadata_segment_collision),
OCF_PL_ARG_INT(metadata_segment_list_info),
OCF_PL_ARG_INT(metadata_segment_hash),
@@ -1092,7 +1099,7 @@ out:
struct ocf_pipeline_arg ocf_metadata_load_all_args[] = {
OCF_PL_ARG_INT(metadata_segment_core_runtime),
OCF_PL_ARG_INT(metadata_segment_cleaning),
- OCF_PL_ARG_INT(metadata_segment_eviction),
+ OCF_PL_ARG_INT(metadata_segment_lru),
OCF_PL_ARG_INT(metadata_segment_collision),
OCF_PL_ARG_INT(metadata_segment_list_info),
OCF_PL_ARG_INT(metadata_segment_hash),
@@ -1146,18 +1153,21 @@ static void _recovery_rebuild_cline_metadata(ocf_cache_t cache,
ocf_core_t core = ocf_cache_get_core(cache, core_id);
ocf_part_id_t part_id;
ocf_cache_line_t hash_index;
+ struct ocf_part_runtime *part;
part_id = PARTITION_DEFAULT;
+ part = cache->user_parts[part_id].part.runtime;
- ocf_metadata_add_to_partition(cache, part_id, cache_line);
+ ocf_metadata_set_partition_id(cache, part_id, cache_line);
+ env_atomic_inc(&part->curr_size);
hash_index = ocf_metadata_hash_func(cache, core_line, core_id);
ocf_metadata_add_to_collision(cache, core_id, core_line, hash_index,
cache_line);
- ocf_eviction_init_cache_line(cache, cache_line);
+ ocf_lru_init_cline(cache, cache_line);
- ocf_eviction_set_hot_cache_line(cache, cache_line);
+ ocf_lru_hot_cline(cache, cache_line);
env_atomic_inc(&core->runtime_meta->cached_clines);
env_atomic_inc(&core->runtime_meta->
diff --git a/src/metadata/metadata_collision.h b/src/metadata/metadata_collision.h
index b4c7bff..debc185 100644
--- a/src/metadata/metadata_collision.h
+++ b/src/metadata/metadata_collision.h
@@ -15,10 +15,6 @@ struct ocf_metadata_list_info {
/*!< Previous cache line in collision list */
ocf_cache_line_t next_col;
/*!< Next cache line in collision list*/
- ocf_cache_line_t partition_prev;
- /*!< Previous cache line in the same partition*/
- ocf_cache_line_t partition_next;
- /*!< Next cache line in the same partition*/
ocf_part_id_t partition_id : 8;
/*!< ID of partition where is assigned this cache line*/
} __attribute__((packed));
diff --git a/src/metadata/metadata_eviction_policy.c b/src/metadata/metadata_eviction_policy.c
index 240c113..19fb3ab 100644
--- a/src/metadata/metadata_eviction_policy.c
+++ b/src/metadata/metadata_eviction_policy.c
@@ -11,15 +11,14 @@
/*
* Eviction policy - Get
*/
-union eviction_policy_meta *
-ocf_metadata_get_eviction_policy(struct ocf_cache *cache,
+struct ocf_lru_meta * ocf_metadata_get_lru(struct ocf_cache *cache,
ocf_cache_line_t line)
{
struct ocf_metadata_ctrl *ctrl
= (struct ocf_metadata_ctrl *) cache->metadata.priv;
return ocf_metadata_raw_wr_access(cache,
- &(ctrl->raw_desc[metadata_segment_eviction]), line);
+ &(ctrl->raw_desc[metadata_segment_lru]), line);
}
diff --git a/src/metadata/metadata_eviction_policy.h b/src/metadata/metadata_eviction_policy.h
index 05987a7..b1e7443 100644
--- a/src/metadata/metadata_eviction_policy.h
+++ b/src/metadata/metadata_eviction_policy.h
@@ -6,8 +6,8 @@
#ifndef __METADATA_EVICTION_H__
#define __METADATA_EVICTION_H__
-union eviction_policy_meta *
-ocf_metadata_get_eviction_policy(
+struct ocf_lru_meta *
+ocf_metadata_get_lru(
struct ocf_cache *cache, ocf_cache_line_t line);
#endif /* METADATA_EVICTION_H_ */
diff --git a/src/metadata/metadata_misc.c b/src/metadata/metadata_misc.c
index 53b9eb0..2e37302 100644
--- a/src/metadata/metadata_misc.c
+++ b/src/metadata/metadata_misc.c
@@ -5,91 +5,8 @@
#include "ocf/ocf.h"
#include "metadata.h"
-#include "../ocf_freelist.h"
#include "../utils/utils_cache_line.h"
-static bool _is_cache_line_acting(struct ocf_cache *cache,
- uint32_t cache_line, ocf_core_id_t core_id,
- uint64_t start_line, uint64_t end_line)
-{
- ocf_core_id_t tmp_core_id;
- uint64_t core_line;
-
- ocf_metadata_get_core_info(cache, cache_line,
- &tmp_core_id, &core_line);
-
- if (core_id != OCF_CORE_ID_INVALID) {
- if (core_id != tmp_core_id)
- return false;
-
- if (core_line < start_line || core_line > end_line)
- return false;
-
- } else if (tmp_core_id == OCF_CORE_ID_INVALID) {
- return false;
- }
-
- return true;
-}
-
-/*
- * Iterates over cache lines that belong to the core device with
- * core ID = core_id whose core byte addresses are in the range
- * [start_byte, end_byte] and applies actor(cache, cache_line) to all
- * matching cache lines
- *
- * set partition_id to PARTITION_INVALID to not care about partition_id
- *
- * METADATA lock must be held before calling this function
- */
-int ocf_metadata_actor(struct ocf_cache *cache,
- ocf_part_id_t part_id, ocf_core_id_t core_id,
- uint64_t start_byte, uint64_t end_byte,
- ocf_metadata_actor_t actor)
-{
- uint32_t step = 0;
- ocf_cache_line_t i, next_i;
- uint64_t start_line, end_line;
- int ret = 0;
- struct ocf_alock *c =
- ocf_cache_line_concurrency(cache);
-
- start_line = ocf_bytes_2_lines(cache, start_byte);
- end_line = ocf_bytes_2_lines(cache, end_byte);
-
- if (part_id != PARTITION_INVALID) {
- for (i = cache->user_parts[part_id].runtime->head;
- i != cache->device->collision_table_entries;
- i = next_i) {
- next_i = ocf_metadata_get_partition_next(cache, i);
-
- if (_is_cache_line_acting(cache, i, core_id,
- start_line, end_line)) {
- if (ocf_cache_line_is_used(c, i))
- ret = -OCF_ERR_AGAIN;
- else
- actor(cache, i);
- }
-
- OCF_COND_RESCHED_DEFAULT(step);
- }
- } else {
- for (i = 0; i < cache->device->collision_table_entries; ++i) {
- if (_is_cache_line_acting(cache, i, core_id,
- start_line, end_line)) {
- if (ocf_cache_line_is_used(c, i))
- ret = -OCF_ERR_AGAIN;
- else
- actor(cache, i);
- }
-
- OCF_COND_RESCHED_DEFAULT(step);
- }
- }
-
- return ret;
-}
-
/* the caller must hold the relevant cache block concurrency reader lock
* and the metadata lock
*/
@@ -100,10 +17,6 @@ void ocf_metadata_remove_cache_line(struct ocf_cache *cache,
ocf_metadata_get_partition_id(cache, cache_line);
ocf_metadata_remove_from_collision(cache, cache_line, partition_id);
-
- ocf_metadata_remove_from_partition(cache, partition_id, cache_line);
-
- ocf_freelist_put_cache_line(cache->freelist, cache_line);
}
void ocf_metadata_sparse_cache_line(struct ocf_cache *cache,
@@ -128,6 +41,6 @@ void ocf_metadata_sparse_cache_line(struct ocf_cache *cache,
int ocf_metadata_sparse_range(struct ocf_cache *cache, int core_id,
uint64_t start_byte, uint64_t end_byte)
{
- return ocf_metadata_actor(cache, PARTITION_INVALID, core_id,
+ return ocf_metadata_actor(cache, PARTITION_UNSPECIFIED, core_id,
start_byte, end_byte, ocf_metadata_sparse_cache_line);
}
diff --git a/src/metadata/metadata_misc.h b/src/metadata/metadata_misc.h
index 50e6201..7e89949 100644
--- a/src/metadata/metadata_misc.h
+++ b/src/metadata/metadata_misc.h
@@ -30,12 +30,4 @@ void ocf_metadata_sparse_cache_line(struct ocf_cache *cache,
int ocf_metadata_sparse_range(struct ocf_cache *cache, int core_id,
uint64_t start_byte, uint64_t end_byte);
-typedef void (*ocf_metadata_actor_t)(struct ocf_cache *cache,
- ocf_cache_line_t cache_line);
-
-int ocf_metadata_actor(struct ocf_cache *cache,
- ocf_part_id_t part_id, ocf_core_id_t core_id,
- uint64_t start_byte, uint64_t end_byte,
- ocf_metadata_actor_t actor);
-
#endif /* __METADATA_MISC_H__ */
diff --git a/src/metadata/metadata_partition.c b/src/metadata/metadata_partition.c
index e14beef..ea2c3be 100644
--- a/src/metadata/metadata_partition.c
+++ b/src/metadata/metadata_partition.c
@@ -6,11 +6,10 @@
#include "ocf/ocf.h"
#include "metadata.h"
#include "metadata_internal.h"
-#include "../utils/utils_part.h"
+#include "../utils/utils_user_part.h"
-void ocf_metadata_get_partition_info(struct ocf_cache *cache,
- ocf_cache_line_t line, ocf_part_id_t *part_id,
- ocf_cache_line_t *next_line, ocf_cache_line_t *prev_line)
+ocf_part_id_t ocf_metadata_get_partition_id(struct ocf_cache *cache,
+ ocf_cache_line_t line)
{
const struct ocf_metadata_list_info *info;
struct ocf_metadata_ctrl *ctrl =
@@ -19,26 +18,13 @@ void ocf_metadata_get_partition_info(struct ocf_cache *cache,
info = ocf_metadata_raw_rd_access(cache,
&(ctrl->raw_desc[metadata_segment_list_info]), line);
- if (info) {
- if (part_id)
- *part_id = info->partition_id;
- if (next_line)
- *next_line = info->partition_next;
- if (prev_line)
- *prev_line = info->partition_prev;
- } else {
- ocf_metadata_error(cache);
- if (part_id)
- *part_id = PARTITION_DEFAULT;
- if (next_line)
- *next_line = cache->device->collision_table_entries;
- if (prev_line)
- *prev_line = cache->device->collision_table_entries;
- }
+ ENV_BUG_ON(!info);
+
+ return info->partition_id;
}
-void ocf_metadata_set_partition_next(struct ocf_cache *cache,
- ocf_cache_line_t line, ocf_cache_line_t next_line)
+void ocf_metadata_set_partition_id(struct ocf_cache *cache,
+ ocf_cache_line_t line, ocf_part_id_t part_id)
{
struct ocf_metadata_list_info *info;
struct ocf_metadata_ctrl *ctrl =
@@ -48,176 +34,7 @@ void ocf_metadata_set_partition_next(struct ocf_cache *cache,
&(ctrl->raw_desc[metadata_segment_list_info]), line);
if (info)
- info->partition_next = next_line;
- else
- ocf_metadata_error(cache);
-}
-
-void ocf_metadata_set_partition_prev(struct ocf_cache *cache,
- ocf_cache_line_t line, ocf_cache_line_t prev_line)
-{
- struct ocf_metadata_list_info *info;
- struct ocf_metadata_ctrl *ctrl =
- (struct ocf_metadata_ctrl *) cache->metadata.priv;
-
- info = ocf_metadata_raw_wr_access(cache,
- &(ctrl->raw_desc[metadata_segment_list_info]), line);
-
- if (info)
- info->partition_prev = prev_line;
- else
- ocf_metadata_error(cache);
-}
-
-void ocf_metadata_set_partition_info(struct ocf_cache *cache,
- ocf_cache_line_t line, ocf_part_id_t part_id,
- ocf_cache_line_t next_line, ocf_cache_line_t prev_line)
-{
- struct ocf_metadata_list_info *info;
- struct ocf_metadata_ctrl *ctrl =
- (struct ocf_metadata_ctrl *) cache->metadata.priv;
-
- info = ocf_metadata_raw_wr_access(cache,
- &(ctrl->raw_desc[metadata_segment_list_info]), line);
-
- if (info) {
info->partition_id = part_id;
- info->partition_next = next_line;
- info->partition_prev = prev_line;
- } else {
+ else
ocf_metadata_error(cache);
- }
-}
-/* Sets the given collision_index as the new _head_ of the Partition list. */
-static void update_partition_head(struct ocf_cache *cache,
- ocf_part_id_t part_id, ocf_cache_line_t line)
-{
- struct ocf_user_part *part = &cache->user_parts[part_id];
-
- part->runtime->head = line;
-}
-
-/* Adds the given collision_index to the _head_ of the Partition list */
-void ocf_metadata_add_to_partition(struct ocf_cache *cache,
- ocf_part_id_t part_id, ocf_cache_line_t line)
-{
- ocf_cache_line_t line_head;
- ocf_cache_line_t line_entries = cache->device->collision_table_entries;
- struct ocf_user_part *part = &cache->user_parts[part_id];
-
- ENV_BUG_ON(!(line < line_entries));
-
- ocf_metadata_partition_lock(&cache->metadata.lock, part_id);
-
- /* First node to be added/ */
- if (!part->runtime->curr_size) {
-
- update_partition_head(cache, part_id, line);
- ocf_metadata_set_partition_info(cache, line, part_id,
- line_entries, line_entries);
-
- if (!ocf_part_is_valid(part)) {
- /* Partition becomes empty, and is not valid
- * update list of partitions
- */
- ocf_part_sort(cache);
- }
-
- } else {
- /* Not the first node to be added. */
- line_head = part->runtime->head;
-
- ENV_BUG_ON(!(line_head < line_entries));
-
- ocf_metadata_set_partition_info(cache, line, part_id,
- line_head, line_entries);
-
- ocf_metadata_set_partition_prev(cache, line_head, line);
-
- update_partition_head(cache, part_id, line);
- }
-
- part->runtime->curr_size++;
-
- ocf_metadata_partition_unlock(&cache->metadata.lock, part_id);
-}
-
-/* Deletes the node with the given collision_index from the Partition list */
-void ocf_metadata_remove_from_partition(struct ocf_cache *cache,
- ocf_part_id_t part_id, ocf_cache_line_t line)
-{
- int is_head, is_tail;
- ocf_cache_line_t prev_line, next_line;
- uint32_t line_entries = cache->device->collision_table_entries;
- struct ocf_user_part *part = &cache->user_parts[part_id];
-
- ENV_BUG_ON(!(line < line_entries));
-
- ocf_metadata_partition_lock(&cache->metadata.lock, part_id);
-
- /* Get Partition info */
- ocf_metadata_get_partition_info(cache, line, NULL,
- &next_line, &prev_line);
-
- /* Find out if this node is Partition _head_ */
- is_head = (prev_line == line_entries);
- is_tail = (next_line == line_entries);
-
- /* Case 1: If we are head and there is only one node. So unlink node
- * and set that there is no node left in the list.
- */
- if (is_head && (part->runtime->curr_size == 1)) {
- ocf_metadata_set_partition_info(cache, line,
- part_id, line_entries, line_entries);
-
- update_partition_head(cache, part_id, line_entries);
-
- if (!ocf_part_is_valid(part)) {
- /* Partition becomes not empty, and is not valid
- * update list of partitions
- */
- ocf_part_sort(cache);
- }
-
- } else if (is_head) {
- /* Case 2: else if this collision_index is partition list head,
- * but many nodes, update head and return
- */
- ENV_BUG_ON(!(next_line < line_entries));
- update_partition_head(cache, part_id, next_line);
-
- ocf_metadata_set_partition_next(cache, line, line_entries);
-
- ocf_metadata_set_partition_prev(cache, next_line,
- line_entries);
- } else if (is_tail) {
- /* Case 3: else if this collision_index is partition list tail
- */
- ENV_BUG_ON(!(prev_line < line_entries));
-
- ocf_metadata_set_partition_prev(cache, line, line_entries);
-
- ocf_metadata_set_partition_next(cache, prev_line,
- line_entries);
- } else {
- /* Case 4: else this collision_index is a middle node.
- * There is no change to the head and the tail pointers.
- */
-
- ENV_BUG_ON(!(next_line < line_entries));
- ENV_BUG_ON(!(prev_line < line_entries));
-
- /* Update prev and next nodes */
- ocf_metadata_set_partition_next(cache, prev_line, next_line);
-
- ocf_metadata_set_partition_prev(cache, next_line, prev_line);
-
- /* Update the given node */
- ocf_metadata_set_partition_info(cache, line, part_id,
- line_entries, line_entries);
- }
-
- part->runtime->curr_size--;
-
- ocf_metadata_partition_unlock(&cache->metadata.lock, part_id);
}
diff --git a/src/metadata/metadata_partition.h b/src/metadata/metadata_partition.h
index f9ae453..be66901 100644
--- a/src/metadata/metadata_partition.h
+++ b/src/metadata/metadata_partition.h
@@ -10,62 +10,16 @@
#include "../ocf_cache_priv.h"
#define PARTITION_DEFAULT 0
-#define PARTITION_INVALID ((ocf_part_id_t)-1)
+#define PARTITION_UNSPECIFIED ((ocf_part_id_t)-1)
+#define PARTITION_FREELIST OCF_USER_IO_CLASS_MAX + 1
#define PARTITION_SIZE_MIN 0
#define PARTITION_SIZE_MAX 100
-void ocf_metadata_get_partition_info(
+ocf_part_id_t ocf_metadata_get_partition_id(struct ocf_cache *cache,
+ ocf_cache_line_t line);
+
+void ocf_metadata_set_partition_id(
struct ocf_cache *cache, ocf_cache_line_t line,
- ocf_part_id_t *part_id, ocf_cache_line_t *next_line,
- ocf_cache_line_t *prev_line);
-
-static inline ocf_part_id_t ocf_metadata_get_partition_id(
- struct ocf_cache *cache, ocf_cache_line_t line)
-{
- ocf_part_id_t part_id;
-
- ocf_metadata_get_partition_info(cache, line, &part_id, NULL, NULL);
-
- return part_id;
-}
-
-static inline ocf_cache_line_t ocf_metadata_get_partition_next(
- struct ocf_cache *cache, ocf_cache_line_t line)
-{
- ocf_cache_line_t next;
-
- ocf_metadata_get_partition_info(cache, line, NULL, &next, NULL);
-
- return next;
-}
-
-static inline ocf_cache_line_t ocf_metadata_get_partition_prev(
- struct ocf_cache *cache, ocf_cache_line_t line)
-{
- ocf_cache_line_t prev;
-
- ocf_metadata_get_partition_info(cache, line, NULL, NULL, &prev);
-
- return prev;
-}
-
-void ocf_metadata_set_partition_next(
- struct ocf_cache *cache, ocf_cache_line_t line,
- ocf_cache_line_t next_line);
-
-void ocf_metadata_set_partition_prev(
- struct ocf_cache *cache, ocf_cache_line_t line,
- ocf_cache_line_t prev_line);
-
-void ocf_metadata_set_partition_info(
- struct ocf_cache *cache, ocf_cache_line_t line,
- ocf_part_id_t part_id, ocf_cache_line_t next_line,
- ocf_cache_line_t prev_line);
-
-void ocf_metadata_add_to_partition(struct ocf_cache *cache,
- ocf_part_id_t part_id, ocf_cache_line_t line);
-
-void ocf_metadata_remove_from_partition(struct ocf_cache *cache,
- ocf_part_id_t part_id, ocf_cache_line_t line);
+ ocf_part_id_t part_id);
#endif /* __METADATA_PARTITION_H__ */
diff --git a/src/metadata/metadata_partition_structs.h b/src/metadata/metadata_partition_structs.h
index 3c4567a..d99ab52 100644
--- a/src/metadata/metadata_partition_structs.h
+++ b/src/metadata/metadata_partition_structs.h
@@ -8,7 +8,9 @@
#include "../utils/utils_list.h"
#include "../cleaning/cleaning.h"
-#include "../eviction/eviction.h"
+#include "../ocf_space.h"
+
+#define OCF_NUM_PARTITIONS OCF_USER_IO_CLASS_MAX + 2
struct ocf_user_part_config {
char name[OCF_IO_CLASS_NAME_MAX];
@@ -26,33 +28,33 @@ struct ocf_user_part_config {
ocf_cache_mode_t cache_mode;
};
-struct ocf_user_part_runtime {
- uint32_t curr_size;
- uint32_t head;
- struct eviction_policy eviction[OCF_NUM_EVICTION_LISTS];
- struct cleaning_policy cleaning;
+struct ocf_part_runtime {
+ env_atomic curr_size;
+ struct ocf_lru_part_meta lru[OCF_NUM_LRU_LISTS];
};
typedef bool ( *_lru_hash_locked_pfn)(struct ocf_request *req,
ocf_core_id_t core_id, uint64_t core_line);
-/* Iterator state, visiting all eviction lists within a partition
+/* Iterator state, visiting all lru lists within a partition
in round robin order */
struct ocf_lru_iter
{
/* per-partition cacheline iterator */
- ocf_cache_line_t curr_cline[OCF_NUM_EVICTION_LISTS];
+ ocf_cache_line_t curr_cline[OCF_NUM_LRU_LISTS];
/* cache object */
ocf_cache_t cache;
+ /* cacheline concurrency */
+ struct ocf_alock *c;
/* target partition */
- struct ocf_user_part *part;
- /* available (non-empty) eviction list bitmap rotated so that current
- @evp is on the most significant bit */
- unsigned long long next_avail_evp;
- /* number of available eviction lists */
- uint32_t num_avail_evps;
- /* current eviction list index */
- uint32_t evp;
+ struct ocf_part *part;
+ /* available (non-empty) lru list bitmap rotated so that current
+ @lru_idx is on the most significant bit */
+ unsigned long long next_avail_lru;
+ /* number of available lru lists */
+ uint32_t num_avail_lrus;
+ /* current lru list index */
+ uint32_t lru_idx;
/* callback to determine whether given hash bucket is already
* locked by the caller */
_lru_hash_locked_pfn hash_locked;
@@ -60,8 +62,6 @@ struct ocf_lru_iter
struct ocf_request *req;
/* 1 if iterating over clean lists, 0 if over dirty */
bool clean : 1;
- /* 1 if cacheline is to be locked for write, 0 if for read*/
- bool cl_lock_write : 1;
};
#define OCF_EVICTION_CLEAN_SIZE 32U
@@ -72,10 +72,18 @@ struct ocf_part_cleaning_ctx {
ocf_cache_line_t cline[OCF_EVICTION_CLEAN_SIZE];
};
+/* common partition data for both user-deined partitions as
+ * well as freelist
+ */
+struct ocf_part {
+ struct ocf_part_runtime *runtime;
+ ocf_part_id_t id;
+};
+
struct ocf_user_part {
struct ocf_user_part_config *config;
- struct ocf_user_part_runtime *runtime;
- ocf_part_id_t id;
+ struct cleaning_policy *clean_pol;
+ struct ocf_part part;
struct ocf_part_cleaning_ctx cleaning;
struct ocf_lst_entry lst_valid;
};
diff --git a/src/metadata/metadata_segment_id.h b/src/metadata/metadata_segment_id.h
index f65c7cd..4e8e9aa 100644
--- a/src/metadata/metadata_segment_id.h
+++ b/src/metadata/metadata_segment_id.h
@@ -32,7 +32,7 @@ enum ocf_metadata_segment_id {
/* sections with size dependent on cache device size go here: */
metadata_segment_cleaning = /*!< Cleaning policy */
metadata_segment_variable_size_start,
- metadata_segment_eviction, /*!< Eviction policy */
+ metadata_segment_lru, /*!< Eviction policy */
metadata_segment_collision, /*!< Collision */
metadata_segment_list_info, /*!< Collision */
metadata_segment_hash, /*!< Hash */
diff --git a/src/metadata/metadata_structs.h b/src/metadata/metadata_structs.h
index a6b2221..ad68244 100644
--- a/src/metadata/metadata_structs.h
+++ b/src/metadata/metadata_structs.h
@@ -7,7 +7,7 @@
#define __METADATA_STRUCTS_H__
#include "metadata_common.h"
-#include "../eviction/eviction.h"
+#include "../ocf_space.h"
#include "../cleaning/cleaning.h"
#include "../ocf_request.h"
@@ -55,8 +55,8 @@ struct ocf_metadata_lock
{
struct ocf_metadata_global_lock global[OCF_NUM_GLOBAL_META_LOCKS];
/*!< global metadata lock (GML) */
- env_rwlock eviction[OCF_NUM_EVICTION_LISTS]; /*!< Fast lock for eviction policy */
- env_spinlock partition[OCF_IO_CLASS_MAX]; /* partition lock */
+ env_rwlock lru[OCF_NUM_LRU_LISTS]; /*!< Fast locks for lru list */
+ env_spinlock partition[OCF_USER_IO_CLASS_MAX]; /* partition lock */
env_rwsem *hash; /*!< Hash bucket locks */
env_rwsem *collision_pages; /*!< Collision table page locks */
ocf_cache_t cache; /*!< Parent cache object */
diff --git a/src/metadata/metadata_superblock.c b/src/metadata/metadata_superblock.c
index 17bc486..00ebb5b 100644
--- a/src/metadata/metadata_superblock.c
+++ b/src/metadata/metadata_superblock.c
@@ -161,7 +161,7 @@ static void ocf_metadata_load_superblock_post(ocf_pipeline_t pipeline,
OCF_PL_FINISH_RET(pipeline, -OCF_ERR_INVAL);
}
- if (sb_config->valid_parts_no > OCF_IO_CLASS_MAX) {
+ if (sb_config->valid_parts_no > OCF_USER_IO_CLASS_MAX) {
ocf_cache_log(cache, log_err,
"Loading cache state ERROR, invalid partition count\n");
OCF_PL_FINISH_RET(pipeline, -OCF_ERR_INVAL);
diff --git a/src/metadata/metadata_superblock.h b/src/metadata/metadata_superblock.h
index cbc866f..032dab3 100644
--- a/src/metadata/metadata_superblock.h
+++ b/src/metadata/metadata_superblock.h
@@ -49,8 +49,6 @@ struct ocf_superblock_config {
ocf_promotion_t promotion_policy_type;
struct promotion_policy_config promotion[PROMOTION_POLICY_TYPE_MAX];
- ocf_eviction_t eviction_policy_type;
-
/*
* Checksum for each metadata region.
* This field has to be the last one!
diff --git a/src/mngt/ocf_mngt_cache.c b/src/mngt/ocf_mngt_cache.c
index 69d8fae..f738392 100644
--- a/src/mngt/ocf_mngt_cache.c
+++ b/src/mngt/ocf_mngt_cache.c
@@ -11,8 +11,9 @@
#include "../ocf_queue_priv.h"
#include "../metadata/metadata.h"
#include "../metadata/metadata_io.h"
+#include "../metadata/metadata_partition_structs.h"
#include "../engine/cache_engine.h"
-#include "../utils/utils_part.h"
+#include "../utils/utils_user_part.h"
#include "../utils/utils_cache_line.h"
#include "../utils/utils_io.h"
#include "../utils/utils_cache_line.h"
@@ -20,9 +21,8 @@
#include "../utils/utils_refcnt.h"
#include "../utils/utils_async_lock.h"
#include "../concurrency/ocf_concurrency.h"
-#include "../eviction/ops.h"
+#include "../ocf_lru.h"
#include "../ocf_ctx_priv.h"
-#include "../ocf_freelist.h"
#include "../cleaning/cleaning.h"
#include "../promotion/ops.h"
@@ -123,8 +123,6 @@ struct ocf_cache_attach_context {
* load or recovery
*/
- bool freelist_inited : 1;
-
bool concurrency_inited : 1;
} flags;
@@ -169,7 +167,7 @@ static void __init_partitions(ocf_cache_t cache)
OCF_IO_CLASS_PRIO_LOWEST, true));
/* Add other partition to the cache and make it as dummy */
- for (i_part = 0; i_part < OCF_IO_CLASS_MAX; i_part++) {
+ for (i_part = 0; i_part < OCF_USER_IO_CLASS_MAX; i_part++) {
ocf_refcnt_freeze(&cache->user_parts[i_part].cleaning.counter);
if (i_part == PARTITION_DEFAULT)
@@ -182,26 +180,22 @@ static void __init_partitions(ocf_cache_t cache)
}
}
-static void __init_partitions_attached(ocf_cache_t cache)
+static void __init_parts_attached(ocf_cache_t cache)
{
- struct ocf_user_part *part;
ocf_part_id_t part_id;
- for (part_id = 0; part_id < OCF_IO_CLASS_MAX; part_id++) {
- part = &cache->user_parts[part_id];
+ for (part_id = 0; part_id < OCF_USER_IO_CLASS_MAX; part_id++)
+ ocf_lru_init(cache, &cache->user_parts[part_id].part);
- part->runtime->head = cache->device->collision_table_entries;
- part->runtime->curr_size = 0;
- ocf_eviction_initialize(cache, part);
- }
+ ocf_lru_init(cache, &cache->free);
}
-static void __init_freelist(ocf_cache_t cache)
+static void __populate_free(ocf_cache_t cache)
{
uint64_t free_clines = ocf_metadata_collision_table_entries(cache) -
ocf_get_cache_occupancy(cache);
- ocf_freelist_populate(cache->freelist, free_clines);
+ ocf_lru_populate(cache, free_clines);
}
static ocf_error_t __init_cleaning_policy(ocf_cache_t cache)
@@ -233,14 +227,6 @@ static void __deinit_cleaning_policy(ocf_cache_t cache)
cleaning_policy_ops[cleaning_policy].deinitialize(cache);
}
-static void __init_eviction_policy(ocf_cache_t cache,
- ocf_eviction_t eviction)
-{
- ENV_BUG_ON(eviction < 0 || eviction >= ocf_eviction_max);
-
- cache->conf_meta->eviction_policy_type = eviction;
-}
-
static void __setup_promotion_policy(ocf_cache_t cache)
{
int i;
@@ -259,6 +245,11 @@ static void __deinit_promotion_policy(ocf_cache_t cache)
cache->promotion_policy = NULL;
}
+static void __init_free(ocf_cache_t cache)
+{
+ cache->free.id = PARTITION_FREELIST;
+}
+
static void __init_cores(ocf_cache_t cache)
{
/* No core devices yet */
@@ -283,7 +274,7 @@ static void __reset_stats(ocf_cache_t cache)
env_atomic_set(&core->runtime_meta->dirty_clines, 0);
env_atomic64_set(&core->runtime_meta->dirty_since, 0);
- for (i = 0; i != OCF_IO_CLASS_MAX; i++) {
+ for (i = 0; i != OCF_USER_IO_CLASS_MAX; i++) {
env_atomic_set(&core->runtime_meta->
part_counters[i].cached_clines, 0);
env_atomic_set(&core->runtime_meta->
@@ -292,8 +283,7 @@ static void __reset_stats(ocf_cache_t cache)
}
}
-static ocf_error_t init_attached_data_structures(ocf_cache_t cache,
- ocf_eviction_t eviction_policy)
+static ocf_error_t init_attached_data_structures(ocf_cache_t cache)
{
ocf_error_t result;
@@ -301,8 +291,8 @@ static ocf_error_t init_attached_data_structures(ocf_cache_t cache,
ocf_metadata_init_hash_table(cache);
ocf_metadata_init_collision(cache);
- __init_partitions_attached(cache);
- __init_freelist(cache);
+ __init_parts_attached(cache);
+ __populate_free(cache);
result = __init_cleaning_policy(cache);
if (result) {
@@ -311,7 +301,6 @@ static ocf_error_t init_attached_data_structures(ocf_cache_t cache,
return result;
}
- __init_eviction_policy(cache, eviction_policy);
__setup_promotion_policy(cache);
return 0;
@@ -321,7 +310,7 @@ static void init_attached_data_structures_recovery(ocf_cache_t cache)
{
ocf_metadata_init_hash_table(cache);
ocf_metadata_init_collision(cache);
- __init_partitions_attached(cache);
+ __init_parts_attached(cache);
__reset_stats(cache);
__init_metadata_version(cache);
}
@@ -477,7 +466,8 @@ void _ocf_mngt_load_init_instance_complete(void *priv, int error)
OCF_PL_FINISH_RET(context->pipeline, -OCF_ERR_START_CACHE_FAIL);
}
- __init_freelist(cache);
+ if (context->metadata.shutdown_status != ocf_metadata_clean_shutdown)
+ __populate_free(cache);
cleaning_policy = cache->conf_meta->cleaning_policy_type;
if (!cleaning_policy_ops[cleaning_policy].initialize)
@@ -685,7 +675,6 @@ static int _ocf_mngt_init_prepare_cache(struct ocf_cache_mngt_init_params *param
cache->pt_unaligned_io = cfg->pt_unaligned_io;
cache->use_submit_io_fast = cfg->use_submit_io_fast;
- cache->eviction_policy_init = cfg->eviction_policy;
cache->metadata.is_volatile = cfg->metadata_volatile;
out:
@@ -996,12 +985,6 @@ static void _ocf_mngt_attach_prepare_metadata(ocf_pipeline_t pipeline,
context->flags.attached_metadata_inited = true;
- ret = ocf_freelist_init(&cache->freelist, cache);
- if (ret)
- OCF_PL_FINISH_RET(pipeline, ret);
-
- context->flags.freelist_inited = true;
-
ret = ocf_concurrency_init(cache);
if (ret)
OCF_PL_FINISH_RET(pipeline, ret);
@@ -1021,7 +1004,7 @@ static void _ocf_mngt_attach_init_instance(ocf_pipeline_t pipeline,
ocf_cache_t cache = context->cache;
ocf_error_t result;
- result = init_attached_data_structures(cache, cache->eviction_policy_init);
+ result = init_attached_data_structures(cache);
if (result)
OCF_PL_FINISH_RET(pipeline, result);
@@ -1147,9 +1130,6 @@ static void _ocf_mngt_attach_handle_error(
if (context->flags.concurrency_inited)
ocf_concurrency_deinit(cache);
- if (context->flags.freelist_inited)
- ocf_freelist_deinit(cache->freelist);
-
if (context->flags.volume_inited)
ocf_volume_deinit(&cache->device->volume);
@@ -1172,7 +1152,8 @@ static void _ocf_mngt_cache_init(ocf_cache_t cache,
INIT_LIST_HEAD(&cache->io_queues);
/* Init Partitions */
- ocf_part_init(cache);
+ ocf_user_part_init(cache);
+ __init_free(cache);
__init_cores(cache);
__init_metadata_version(cache);
@@ -1886,11 +1867,6 @@ static int _ocf_mngt_cache_validate_cfg(struct ocf_mngt_cache_config *cfg)
if (!ocf_cache_mode_is_valid(cfg->cache_mode))
return -OCF_ERR_INVALID_CACHE_MODE;
- if (cfg->eviction_policy >= ocf_eviction_max ||
- cfg->eviction_policy < 0) {
- return -OCF_ERR_INVAL;
- }
-
if (cfg->promotion_policy >= ocf_promotion_max ||
cfg->promotion_policy < 0 ) {
return -OCF_ERR_INVAL;
@@ -2025,7 +2001,6 @@ static void _ocf_mngt_cache_unplug_complete(void *priv, int error)
ocf_metadata_deinit_variable_size(cache);
ocf_concurrency_deinit(cache);
- ocf_freelist_deinit(cache->freelist);
ocf_volume_deinit(&cache->device->volume);
@@ -2092,15 +2067,12 @@ static int _ocf_mngt_cache_load_core_log(ocf_core_t core, void *cntx)
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",
_ocf_cache_mode_get_name(cache_mode));
- ocf_cache_log(cache, log_info, "Eviction policy : %s\n",
- 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",
diff --git a/src/mngt/ocf_mngt_common.c b/src/mngt/ocf_mngt_common.c
index a40eb42..34965b4 100644
--- a/src/mngt/ocf_mngt_common.c
+++ b/src/mngt/ocf_mngt_common.c
@@ -11,7 +11,7 @@
#include "../metadata/metadata.h"
#include "../engine/cache_engine.h"
#include "../ocf_request.h"
-#include "../eviction/ops.h"
+#include "../ocf_lru.h"
#include "../ocf_logger_priv.h"
#include "../ocf_queue_priv.h"
#include "../engine/engine_common.h"
diff --git a/src/mngt/ocf_mngt_core.c b/src/mngt/ocf_mngt_core.c
index 30614a4..6c7f7c9 100644
--- a/src/mngt/ocf_mngt_core.c
+++ b/src/mngt/ocf_mngt_core.c
@@ -457,7 +457,7 @@ static void ocf_mngt_cache_add_core_insert(ocf_pipeline_t pipeline,
env_atomic_set(&core->runtime_meta->dirty_clines, 0);
env_atomic64_set(&core->runtime_meta->dirty_since, 0);
- for (i = 0; i != OCF_IO_CLASS_MAX; i++) {
+ for (i = 0; i != OCF_USER_IO_CLASS_MAX; i++) {
env_atomic_set(&core->runtime_meta->
part_counters[i].cached_clines, 0);
env_atomic_set(&core->runtime_meta->
diff --git a/src/mngt/ocf_mngt_flush.c b/src/mngt/ocf_mngt_flush.c
index 5e5f008..6b4a549 100644
--- a/src/mngt/ocf_mngt_flush.c
+++ b/src/mngt/ocf_mngt_flush.c
@@ -12,7 +12,7 @@
#include "../engine/engine_common.h"
#include "../utils/utils_cleaner.h"
#include "../utils/utils_cache_line.h"
-#include "../utils/utils_part.h"
+#include "../utils/utils_user_part.h"
#include "../utils/utils_pipeline.h"
#include "../utils/utils_refcnt.h"
#include "../ocf_request.h"
diff --git a/src/mngt/ocf_mngt_io_class.c b/src/mngt/ocf_mngt_io_class.c
index 9685c97..ada3ef3 100644
--- a/src/mngt/ocf_mngt_io_class.c
+++ b/src/mngt/ocf_mngt_io_class.c
@@ -8,19 +8,19 @@
#include "../ocf_priv.h"
#include "../metadata/metadata.h"
#include "../engine/cache_engine.h"
-#include "../utils/utils_part.h"
-#include "../eviction/ops.h"
+#include "../utils/utils_user_part.h"
+#include "../ocf_lru.h"
#include "ocf_env.h"
-static uint64_t _ocf_mngt_count_parts_min_size(struct ocf_cache *cache)
+static uint64_t _ocf_mngt_count_user_parts_min_size(struct ocf_cache *cache)
{
- struct ocf_user_part *part;
+ struct ocf_user_part *user_part;
ocf_part_id_t part_id;
uint64_t count = 0;
- for_each_part(cache, part, part_id) {
- if (ocf_part_is_valid(part))
- count += part->config->min_size;
+ for_each_user_part(cache, user_part, part_id) {
+ if (ocf_user_part_is_valid(user_part))
+ count += user_part->config->min_size;
}
return count;
@@ -37,7 +37,7 @@ int ocf_mngt_add_partition_to_cache(struct ocf_cache *cache,
if (!name)
return -OCF_ERR_INVAL;
- if (part_id >= OCF_IO_CLASS_MAX)
+ if (part_id >= OCF_USER_IO_CLASS_MAX)
return -OCF_ERR_INVAL;
if (cache->user_parts[part_id].config->flags.valid)
@@ -56,7 +56,7 @@ int ocf_mngt_add_partition_to_cache(struct ocf_cache *cache,
return -OCF_ERR_INVAL;
}
- for_each_lst(&cache->lst_part, iter, iter_id) {
+ for_each_lst(&cache->user_part_list, iter, iter_id) {
if (iter_id == part_id) {
ocf_cache_log(cache, log_err,
"Part with id %hu already exists\n", part_id);
@@ -73,9 +73,9 @@ int ocf_mngt_add_partition_to_cache(struct ocf_cache *cache,
cache->user_parts[part_id].config->priority = priority;
cache->user_parts[part_id].config->cache_mode = ocf_cache_mode_max;
- ocf_part_set_valid(cache, part_id, valid);
- ocf_lst_add(&cache->lst_part, part_id);
- ocf_part_sort(cache);
+ ocf_user_part_set_valid(cache, part_id, valid);
+ ocf_lst_add(&cache->user_part_list, part_id);
+ ocf_user_part_sort(cache);
cache->user_parts[part_id].config->flags.added = 1;
@@ -85,12 +85,13 @@ int ocf_mngt_add_partition_to_cache(struct ocf_cache *cache,
static int _ocf_mngt_set_partition_size(struct ocf_cache *cache,
ocf_part_id_t part_id, uint32_t min, uint32_t max)
{
- struct ocf_user_part *part = &cache->user_parts[part_id];
+ struct ocf_user_part *user_part = &cache->user_parts[part_id];
if (min > max)
return -OCF_ERR_INVAL;
- if (_ocf_mngt_count_parts_min_size(cache) + min > PARTITION_SIZE_MAX) {
+ if (_ocf_mngt_count_user_parts_min_size(cache) + min >
+ PARTITION_SIZE_MAX) {
/* Illegal configuration in which sum of all min_sizes exceeds
* cache size.
*/
@@ -100,8 +101,8 @@ static int _ocf_mngt_set_partition_size(struct ocf_cache *cache,
if (max > PARTITION_SIZE_MAX)
max = PARTITION_SIZE_MAX;
- part->config->min_size = min;
- part->config->max_size = max;
+ user_part->config->min_size = min;
+ user_part->config->max_size = max;
return 0;
}
@@ -123,7 +124,7 @@ static int _ocf_mngt_io_class_configure(ocf_cache_t cache,
dest_part = &cache->user_parts[part_id];
- if (!ocf_part_is_added(dest_part)) {
+ if (!ocf_user_part_is_added(dest_part)) {
ocf_cache_log(cache, log_info, "Setting IO class, id: %u, "
"name: '%s' [ ERROR ]\n", part_id, dest_part->config->name);
return -OCF_ERR_INVAL;
@@ -150,7 +151,7 @@ static int _ocf_mngt_io_class_configure(ocf_cache_t cache,
" [ ERROR ]\n", part_id, dest_part->config->name, max);
return -OCF_ERR_INVAL;
}
- ocf_part_set_prio(cache, dest_part, prio);
+ ocf_user_part_set_prio(cache, dest_part, prio);
dest_part->config->cache_mode = cache_mode;
ocf_cache_log(cache, log_info,
@@ -175,21 +176,21 @@ static int _ocf_mngt_io_class_configure(ocf_cache_t cache,
return -OCF_ERR_INVAL;
}
- if (ocf_part_is_valid(dest_part)) {
+ if (ocf_user_part_is_valid(dest_part)) {
/* Updating existing */
ocf_cache_log(cache, log_info, "Updating existing IO "
"class, id: %u, name: '%s', max size %u%% [ OK ]\n",
part_id, dest_part->config->name, max);
} else {
/* Adding new */
- ocf_part_set_valid(cache, part_id, true);
+ ocf_user_part_set_valid(cache, part_id, true);
ocf_cache_log(cache, log_info, "Adding new IO class, "
"id: %u, name: '%s', max size %u%% [ OK ]\n", part_id,
dest_part->config->name, max);
}
- ocf_part_set_prio(cache, dest_part, prio);
+ ocf_user_part_set_prio(cache, dest_part, prio);
dest_part->config->cache_mode = cache_mode;
return result;
@@ -212,13 +213,13 @@ static void _ocf_mngt_io_class_remove(ocf_cache_t cache,
return;
}
- if (!ocf_part_is_valid(dest_part)) {
+ if (!ocf_user_part_is_valid(dest_part)) {
/* Does not exist */
return;
}
- ocf_part_set_valid(cache, part_id, false);
+ ocf_user_part_set_valid(cache, part_id, false);
ocf_cache_log(cache, log_info,
"Removing IO class, id: %u [ OK ]\n", part_id);
@@ -240,7 +241,7 @@ static int _ocf_mngt_io_class_edit(ocf_cache_t cache,
static int _ocf_mngt_io_class_validate_cfg(ocf_cache_t cache,
const struct ocf_mngt_io_class_config *cfg)
{
- if (cfg->class_id >= OCF_IO_CLASS_MAX)
+ if (cfg->class_id >= OCF_USER_IO_CLASS_MAX)
return -OCF_ERR_INVAL;
/* Name set to null means particular io_class should be removed */
@@ -252,13 +253,13 @@ static int _ocf_mngt_io_class_validate_cfg(ocf_cache_t cache,
return -OCF_ERR_INVAL;
}
- if (!ocf_part_is_name_valid(cfg->name)) {
+ if (!ocf_user_part_is_name_valid(cfg->name)) {
ocf_cache_log(cache, log_info,
"The name of the partition is not valid\n");
return -OCF_ERR_INVAL;
}
- if (!ocf_part_is_prio_valid(cfg->prio)) {
+ if (!ocf_user_part_is_prio_valid(cfg->prio)) {
ocf_cache_log(cache, log_info,
"Invalid value of the partition priority\n");
return -OCF_ERR_INVAL;
@@ -284,7 +285,7 @@ int ocf_mngt_cache_io_classes_configure(ocf_cache_t cache,
OCF_CHECK_NULL(cache);
OCF_CHECK_NULL(cfg);
- for (i = 0; i < OCF_IO_CLASS_MAX; i++) {
+ for (i = 0; i < OCF_USER_IO_CLASS_MAX; i++) {
result = _ocf_mngt_io_class_validate_cfg(cache, &cfg->config[i]);
if (result)
return result;
@@ -301,7 +302,7 @@ int ocf_mngt_cache_io_classes_configure(ocf_cache_t cache,
if (result)
goto out_cpy;
- for (i = 0; i < OCF_IO_CLASS_MAX; i++) {
+ for (i = 0; i < OCF_USER_IO_CLASS_MAX; i++) {
result = _ocf_mngt_io_class_edit(cache, &cfg->config[i]);
if (result) {
ocf_cache_log(cache, log_err,
@@ -310,7 +311,7 @@ int ocf_mngt_cache_io_classes_configure(ocf_cache_t cache,
}
}
- ocf_part_sort(cache);
+ ocf_user_part_sort(cache);
out_edit:
if (result) {
diff --git a/src/ocf_cache.c b/src/ocf_cache.c
index f91253e..cc29a49 100644
--- a/src/ocf_cache.c
+++ b/src/ocf_cache.c
@@ -8,7 +8,7 @@
#include "engine/cache_engine.h"
#include "utils/utils_cache_line.h"
#include "ocf_request.h"
-#include "utils/utils_part.h"
+#include "utils/utils_user_part.h"
#include "ocf_priv.h"
#include "ocf_cache_priv.h"
#include "ocf_queue_priv.h"
@@ -170,7 +170,6 @@ int ocf_cache_get_info(ocf_cache_t cache, struct ocf_cache_info *info)
info->fallback_pt.error_counter =
env_atomic_read(&cache->fallback_pt_error_counter);
- info->eviction_policy = cache->conf_meta->eviction_policy_type;
info->cleaning_policy = cache->conf_meta->cleaning_policy_type;
info->promotion_policy = cache->conf_meta->promotion_policy_type;
info->metadata_footprint = ocf_cache_is_device_attached(cache) ?
diff --git a/src/ocf_cache_priv.h b/src/ocf_cache_priv.h
index 67800a6..858ba8c 100644
--- a/src/ocf_cache_priv.h
+++ b/src/ocf_cache_priv.h
@@ -21,7 +21,6 @@
#include "ocf_logger_priv.h"
#include "ocf/ocf_trace.h"
#include "promotion/promotion.h"
-#include "ocf_freelist.h"
#define DIRTY_FLUSHED 1
#define DIRTY_NOT_FLUSHED 0
@@ -77,12 +76,10 @@ struct ocf_cache {
struct ocf_cache_device *device;
- struct ocf_lst lst_part;
- struct ocf_user_part user_parts[OCF_IO_CLASS_MAX + 1];
+ struct ocf_lst user_part_list;
+ struct ocf_user_part user_parts[OCF_USER_IO_CLASS_MAX + 1];
- ocf_freelist_t freelist;
-
- ocf_eviction_t eviction_policy_init;
+ struct ocf_part free;
uint32_t fallback_pt_error_threshold;
ocf_queue_t mngt_queue;
diff --git a/src/ocf_core.c b/src/ocf_core.c
index 3983e5c..a7c7ea3 100644
--- a/src/ocf_core.c
+++ b/src/ocf_core.c
@@ -9,7 +9,7 @@
#include "ocf_io_priv.h"
#include "metadata/metadata.h"
#include "engine/cache_engine.h"
-#include "utils/utils_part.h"
+#include "utils/utils_user_part.h"
#include "ocf_request.h"
#include "ocf_trace_priv.h"
@@ -186,7 +186,7 @@ static inline int ocf_core_validate_io(struct ocf_io *io)
if (io->addr + io->bytes > ocf_volume_get_length(volume))
return -OCF_ERR_INVAL;
- if (io->io_class >= OCF_IO_CLASS_MAX)
+ if (io->io_class >= OCF_USER_IO_CLASS_MAX)
return -OCF_ERR_INVAL;
if (io->dir != OCF_READ && io->dir != OCF_WRITE)
@@ -248,7 +248,7 @@ void ocf_core_volume_submit_io(struct ocf_io *io)
return;
}
- req->part_id = ocf_part_class2id(cache, io->io_class);
+ req->part_id = ocf_user_part_class2id(cache, io->io_class);
req->core = core;
req->complete = ocf_req_complete;
@@ -310,7 +310,7 @@ int ocf_core_submit_io_fast(struct ocf_io *io)
req->core = core;
req->complete = ocf_req_complete;
- req->part_id = ocf_part_class2id(cache, io->io_class);
+ req->part_id = ocf_user_part_class2id(cache, io->io_class);
ocf_resolve_effective_cache_mode(cache, core, req);
diff --git a/src/ocf_core_priv.h b/src/ocf_core_priv.h
index ad52771..766f71a 100644
--- a/src/ocf_core_priv.h
+++ b/src/ocf_core_priv.h
@@ -70,7 +70,7 @@ struct ocf_core_meta_runtime {
* cache device
*/
env_atomic dirty_clines;
- } part_counters[OCF_IO_CLASS_MAX];
+ } part_counters[OCF_USER_IO_CLASS_MAX];
};
struct ocf_core {
diff --git a/src/ocf_freelist.c b/src/ocf_freelist.c
deleted file mode 100644
index 77000c3..0000000
--- a/src/ocf_freelist.c
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * Copyright(c) 2019-2021 Intel Corporation
- * SPDX-License-Identifier: BSD-3-Clause-Clear
- */
-
-#include "ocf/ocf.h"
-#include "metadata/metadata.h"
-
-struct ocf_part {
- ocf_cache_line_t head;
- ocf_cache_line_t tail;
- env_atomic64 curr_size;
-};
-
-struct ocf_freelist {
- /* parent cache */
- struct ocf_cache *cache;
-
- /* partition list array */
- struct ocf_part *part;
-
- /* freelist lock array */
- env_spinlock *lock;
-
- /* number of free lists */
- uint32_t count;
-
- /* next slowpath victim idx */
- env_atomic slowpath_victim_idx;
-
- /* total number of free lines */
- env_atomic64 total_free;
-};
-
-static void ocf_freelist_lock(ocf_freelist_t freelist, uint32_t ctx)
-{
- env_spinlock_lock(&freelist->lock[ctx]);
-}
-
-static int ocf_freelist_trylock(ocf_freelist_t freelist, uint32_t ctx)
-{
- return env_spinlock_trylock(&freelist->lock[ctx]);
-}
-
-static void ocf_freelist_unlock(ocf_freelist_t freelist, uint32_t ctx)
-{
- env_spinlock_unlock(&freelist->lock[ctx]);
-}
-
-/* Sets the given collision_index as the new _head_ of the Partition list. */
-static void _ocf_freelist_remove_cache_line(ocf_freelist_t freelist,
- uint32_t ctx, ocf_cache_line_t cline)
-{
- struct ocf_cache *cache = freelist->cache;
- struct ocf_part *freelist_part = &freelist->part[ctx];
- int is_head, is_tail;
- ocf_part_id_t invalid_part_id = PARTITION_INVALID;
- ocf_cache_line_t prev, next;
- ocf_cache_line_t line_entries = ocf_metadata_collision_table_entries(
- freelist->cache);
- uint32_t free;
-
- ENV_BUG_ON(cline >= line_entries);
-
- /* Get Partition info */
- ocf_metadata_get_partition_info(cache, cline, NULL, &next, &prev);
-
- /* Find out if this node is Partition _head_ */
- is_head = (prev == line_entries);
- is_tail = (next == line_entries);
-
- free = env_atomic64_read(&freelist_part->curr_size);
-
- /* Case 1: If we are head and there is only one node. So unlink node
- * and set that there is no node left in the list.
- */
- if (is_head && free == 1) {
- ocf_metadata_set_partition_info(cache, cline, invalid_part_id,
- line_entries, line_entries);
- freelist_part->head = line_entries;
- freelist_part->tail = line_entries;
- } else if (is_head) {
- /* Case 2: else if this collision_index is partition list head,
- * but many nodes, update head and return
- */
- ENV_BUG_ON(next >= line_entries);
-
- freelist_part->head = next;
- ocf_metadata_set_partition_prev(cache, next, line_entries);
- ocf_metadata_set_partition_next(cache, cline, line_entries);
- } else if (is_tail) {
- /* Case 3: else if this cline is partition list tail */
- ENV_BUG_ON(prev >= line_entries);
-
- freelist_part->tail = prev;
- ocf_metadata_set_partition_prev(cache, cline, line_entries);
- ocf_metadata_set_partition_next(cache, prev, line_entries);
- } else {
- /* Case 4: else this collision_index is a middle node.
- * There is no change to the head and the tail pointers.
- */
-
- ENV_BUG_ON(next >= line_entries || prev >= line_entries);
-
- /* Update prev and next nodes */
- ocf_metadata_set_partition_prev(cache, next, prev);
- ocf_metadata_set_partition_next(cache, prev, next);
-
- /* Update the given node */
- ocf_metadata_set_partition_info(cache, cline, invalid_part_id,
- line_entries, line_entries);
- }
-
- env_atomic64_dec(&freelist_part->curr_size);
- env_atomic64_dec(&freelist->total_free);
-}
-
-static ocf_cache_line_t next_phys_invalid(ocf_cache_t cache,
- ocf_cache_line_t phys)
-{
- ocf_cache_line_t lg;
- ocf_cache_line_t collision_table_entries =
- ocf_metadata_collision_table_entries(cache);
-
- if (phys == collision_table_entries)
- return collision_table_entries;
-
- lg = ocf_metadata_map_phy2lg(cache, phys);
- while (metadata_test_valid_any(cache, lg)) {
- ++phys;
-
- if (phys == collision_table_entries)
- break;
-
- lg = ocf_metadata_map_phy2lg(cache, phys);
- }
-
- return phys;
-}
-
-/* Assign unused cachelines to freelist */
-void ocf_freelist_populate(ocf_freelist_t freelist,
- ocf_cache_line_t num_free_clines)
-{
- unsigned step = 0;
- ocf_cache_t cache = freelist->cache;
- unsigned num_freelists = freelist->count;
- ocf_cache_line_t prev, next, idx;
- ocf_cache_line_t phys;
- ocf_cache_line_t collision_table_entries =
- ocf_metadata_collision_table_entries(cache);
- unsigned freelist_idx;
- uint64_t freelist_size;
-
- phys = 0;
- for (freelist_idx = 0; freelist_idx < num_freelists; freelist_idx++)
- {
- /* calculate current freelist size */
- freelist_size = num_free_clines / num_freelists;
- if (freelist_idx < (num_free_clines % num_freelists))
- ++freelist_size;
-
- env_atomic64_set(&freelist->part[freelist_idx].curr_size,
- freelist_size);
-
- if (!freelist_size) {
- /* init empty freelist and move to next one */
- freelist->part[freelist_idx].head =
- collision_table_entries;
- freelist->part[freelist_idx].tail =
- collision_table_entries;
- continue;
- }
-
- /* find first invalid cacheline */
- phys = next_phys_invalid(cache, phys);
- ENV_BUG_ON(phys == collision_table_entries);
- idx = ocf_metadata_map_phy2lg(cache, phys);
- ++phys;
-
- /* store freelist head */
- freelist->part[freelist_idx].head = idx;
-
- /* link freelist elements using partition list */
- prev = collision_table_entries;
- while (--freelist_size) {
- phys = next_phys_invalid(cache, phys);
- ENV_BUG_ON(phys == collision_table_entries);
- next = ocf_metadata_map_phy2lg(cache, phys);
- ++phys;
-
- ocf_metadata_set_partition_info(cache, idx,
- PARTITION_INVALID, next, prev);
-
- prev = idx;
- idx = next;
-
- OCF_COND_RESCHED_DEFAULT(step);
- }
-
- /* terminate partition list */
- ocf_metadata_set_partition_info(cache, idx, PARTITION_INVALID,
- collision_table_entries, prev);
-
- /* store freelist tail */
- freelist->part[freelist_idx].tail = idx;
- }
-
- /* we should have reached the last invalid cache line */
- phys = next_phys_invalid(cache, phys);
- ENV_BUG_ON(phys != collision_table_entries);
-
- env_atomic64_set(&freelist->total_free, num_free_clines);
-}
-
-static void ocf_freelist_add_cache_line(ocf_freelist_t freelist,
- uint32_t ctx, ocf_cache_line_t line)
-{
- struct ocf_cache *cache = freelist->cache;
- struct ocf_part *freelist_part = &freelist->part[ctx];
- ocf_cache_line_t tail;
- ocf_cache_line_t line_entries = ocf_metadata_collision_table_entries(
- freelist->cache);
- ocf_part_id_t invalid_part_id = PARTITION_INVALID;
-
- ENV_BUG_ON(line >= line_entries);
-
- if (env_atomic64_read(&freelist_part->curr_size) == 0) {
- freelist_part->head = line;
- freelist_part->tail = line;
-
- ocf_metadata_set_partition_info(cache, line, invalid_part_id,
- line_entries, line_entries);
- } else {
- tail = freelist_part->tail;
-
- ENV_BUG_ON(tail >= line_entries);
-
- ocf_metadata_set_partition_info(cache, line, invalid_part_id,
- line_entries, tail);
- ocf_metadata_set_partition_next(cache, tail, line);
-
- freelist_part->tail = line;
- }
-
- env_atomic64_inc(&freelist_part->curr_size);
- env_atomic64_inc(&freelist->total_free);
-}
-
-typedef enum {
- OCF_FREELIST_ERR_NOLOCK = 1,
- OCF_FREELIST_ERR_LIST_EMPTY,
-} ocf_freelist_get_err_t;
-
-static ocf_freelist_get_err_t ocf_freelist_get_cache_line_ctx(
- ocf_freelist_t freelist, uint32_t ctx, bool can_wait,
- ocf_cache_line_t *cline)
-{
- if (env_atomic64_read(&freelist->part[ctx].curr_size) == 0)
- return -OCF_FREELIST_ERR_LIST_EMPTY;
-
- if (!can_wait && ocf_freelist_trylock(freelist, ctx))
- return -OCF_FREELIST_ERR_NOLOCK;
-
- if (can_wait)
- ocf_freelist_lock(freelist, ctx);
-
- if (env_atomic64_read(&freelist->part[ctx].curr_size) == 0) {
- ocf_freelist_unlock(freelist, ctx);
- return -OCF_FREELIST_ERR_LIST_EMPTY;
- }
-
- *cline = freelist->part[ctx].head;
- _ocf_freelist_remove_cache_line(freelist, ctx, *cline);
-
- ocf_freelist_unlock(freelist, ctx);
-
- return 0;
-}
-
-static int get_next_victim_freelist(ocf_freelist_t freelist)
-{
- int ctx, next;
-
- do {
- ctx = env_atomic_read(&freelist->slowpath_victim_idx);
- next = (ctx + 1) % freelist->count;
- } while (ctx != env_atomic_cmpxchg(&freelist->slowpath_victim_idx, ctx,
- next));
-
- return ctx;
-}
-
-static bool ocf_freelist_get_cache_line_slow(ocf_freelist_t freelist,
- ocf_cache_line_t *cline)
-{
- int i, ctx;
- int err;
- bool lock_err;
-
- /* try slowpath without waiting on lock */
- lock_err = false;
- for (i = 0; i < freelist->count; i++) {
- ctx = get_next_victim_freelist(freelist);
- err = ocf_freelist_get_cache_line_ctx(freelist, ctx, false,
- cline);
- if (!err)
- return true;
- if (err == -OCF_FREELIST_ERR_NOLOCK)
- lock_err = true;
- }
-
- if (!lock_err) {
- /* Slowpath failed due to empty freelists - no point in
- * iterating through contexts to attempt slowpath with full
- * lock */
- return false;
- }
-
- /* slow path with waiting on lock */
- for (i = 0; i < freelist->count; i++) {
- ctx = get_next_victim_freelist(freelist);
- if (!ocf_freelist_get_cache_line_ctx(freelist, ctx, true,
- cline)) {
- return true;
- }
- }
-
- return false;
-}
-
-static bool ocf_freelist_get_cache_line_fast(ocf_freelist_t freelist,
- ocf_cache_line_t *cline)
-{
- bool ret;
- uint32_t ctx = env_get_execution_context();
-
- ret = !ocf_freelist_get_cache_line_ctx(freelist, ctx, false, cline);
-
- env_put_execution_context(ctx);
-
- return ret;
-}
-
-bool ocf_freelist_get_cache_line(ocf_freelist_t freelist,
- ocf_cache_line_t *cline)
-{
- if (env_atomic64_read(&freelist->total_free) == 0)
- return false;
-
- if (!ocf_freelist_get_cache_line_fast(freelist, cline))
- return ocf_freelist_get_cache_line_slow(freelist, cline);
-
- return true;
-}
-
-void ocf_freelist_put_cache_line(ocf_freelist_t freelist,
- ocf_cache_line_t cline)
-{
- uint32_t ctx = env_get_execution_context();
-
- ocf_freelist_lock(freelist, ctx);
- ocf_freelist_add_cache_line(freelist, ctx, cline);
- ocf_freelist_unlock(freelist, ctx);
- env_put_execution_context(ctx);
-}
-
-int ocf_freelist_init(ocf_freelist_t *freelist, struct ocf_cache *cache)
-{
- uint32_t num;
- int i;
- int result;
- ocf_freelist_t tmp_freelist;
- ocf_cache_line_t line_entries = ocf_metadata_collision_table_entries(
- cache);
-
- tmp_freelist = env_vzalloc(sizeof(*tmp_freelist));
- if (!tmp_freelist)
- return -OCF_ERR_NO_MEM;
-
- num = env_get_execution_context_count();
-
- tmp_freelist->cache = cache;
- tmp_freelist->count = num;
- env_atomic64_set(&tmp_freelist->total_free, 0);
- tmp_freelist->lock = env_vzalloc(sizeof(tmp_freelist->lock[0]) * num);
- tmp_freelist->part = env_vzalloc(sizeof(tmp_freelist->part[0]) * num);
-
- if (!tmp_freelist->lock || !tmp_freelist->part) {
- result = -OCF_ERR_NO_MEM;
- goto free_allocs;
- }
-
- for (i = 0; i < num; i++) {
- result = env_spinlock_init(&tmp_freelist->lock[i]);
- if (result)
- goto spinlock_err;
-
- tmp_freelist->part[i].head = line_entries;
- tmp_freelist->part[i].tail = line_entries;
- env_atomic64_set(&tmp_freelist->part[i].curr_size, 0);
- }
-
- *freelist = tmp_freelist;
- return 0;
-
-spinlock_err:
- while (i--)
- env_spinlock_destroy(&tmp_freelist->lock[i]);
-free_allocs:
- env_vfree(tmp_freelist->lock);
- env_vfree(tmp_freelist->part);
- env_vfree(tmp_freelist);
- return result;
-}
-
-void ocf_freelist_deinit(ocf_freelist_t freelist)
-{
- int i;
-
- for (i = 0; i < freelist->count; i++)
- env_spinlock_destroy(&freelist->lock[i]);
- env_vfree(freelist->lock);
- env_vfree(freelist->part);
- env_vfree(freelist);
-}
-
-ocf_cache_line_t ocf_freelist_num_free(ocf_freelist_t freelist)
-{
- return env_atomic64_read(&freelist->total_free);
-}
-
diff --git a/src/ocf_freelist.h b/src/ocf_freelist.h
deleted file mode 100644
index 617386d..0000000
--- a/src/ocf_freelist.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright(c) 2019-2021 Intel Corporation
- * SPDX-License-Identifier: BSD-3-Clause-Clear
- */
-
-#ifndef __OCF_FREELIST_H__
-#define __OCF_FREELIST_H__
-
-#include "ocf_cache_priv.h"
-
-struct ocf_freelist;
-
-typedef struct ocf_freelist *ocf_freelist_t;
-
-/* Init / deinit freelist runtime structures */
-int ocf_freelist_init(ocf_freelist_t *freelist, struct ocf_cache *cache);
-void ocf_freelist_deinit(ocf_freelist_t freelist);
-
-/* Assign unused cachelines to freelist */
-void ocf_freelist_populate(ocf_freelist_t freelist,
- ocf_cache_line_t num_free_clines);
-
-/* Get cacheline from freelist */
-bool ocf_freelist_get_cache_line(ocf_freelist_t freelist,
- ocf_cache_line_t *cline);
-
-/* Put cacheline back to freelist */
-void ocf_freelist_put_cache_line(ocf_freelist_t freelist,
- ocf_cache_line_t cline);
-
-/* Return total number of free cachelines */
-ocf_cache_line_t ocf_freelist_num_free(ocf_freelist_t freelist);
-
-#endif /* __OCF_FREELIST_H__ */
diff --git a/src/ocf_io_class.c b/src/ocf_io_class.c
index bbb0095..008cba8 100644
--- a/src/ocf_io_class.c
+++ b/src/ocf_io_class.c
@@ -7,22 +7,23 @@
#include "ocf_priv.h"
#include "metadata/metadata.h"
#include "engine/cache_engine.h"
-#include "utils/utils_part.h"
+#include "utils/utils_user_part.h"
int ocf_cache_io_class_get_info(ocf_cache_t cache, uint32_t io_class,
struct ocf_io_class_info *info)
{
ocf_part_id_t part_id = io_class;
+ struct ocf_part *part;
OCF_CHECK_NULL(cache);
if (!info)
return -OCF_ERR_INVAL;
- if (io_class >= OCF_IO_CLASS_MAX)
+ if (io_class >= OCF_USER_IO_CLASS_MAX)
return -OCF_ERR_INVAL;
- if (!ocf_part_is_valid(&cache->user_parts[part_id])) {
+ if (!ocf_user_part_is_valid(&cache->user_parts[part_id])) {
/* Partition does not exist */
return -OCF_ERR_IO_CLASS_NOT_EXIST;
}
@@ -33,13 +34,14 @@ int ocf_cache_io_class_get_info(ocf_cache_t cache, uint32_t io_class,
return -OCF_ERR_INVAL;
}
+ part = &cache->user_parts[part_id].part;
+
info->priority = cache->user_parts[part_id].config->priority;
info->curr_size = ocf_cache_is_device_attached(cache) ?
- cache->user_parts[part_id].runtime->curr_size : 0;
+ env_atomic_read(&part->runtime->curr_size) : 0;
info->min_size = cache->user_parts[part_id].config->min_size;
info->max_size = cache->user_parts[part_id].config->max_size;
- info->eviction_policy_type = cache->conf_meta->eviction_policy_type;
info->cleaning_policy_type = cache->conf_meta->cleaning_policy_type;
info->cache_mode = cache->user_parts[part_id].config->cache_mode;
@@ -50,7 +52,7 @@ int ocf_cache_io_class_get_info(ocf_cache_t cache, uint32_t io_class,
int ocf_io_class_visit(ocf_cache_t cache, ocf_io_class_visitor_t visitor,
void *cntx)
{
- struct ocf_user_part *part;
+ struct ocf_user_part *user_part;
ocf_part_id_t part_id;
int result = 0;
@@ -59,8 +61,8 @@ int ocf_io_class_visit(ocf_cache_t cache, ocf_io_class_visitor_t visitor,
if (!visitor)
return -OCF_ERR_INVAL;
- for_each_part(cache, part, part_id) {
- if (!ocf_part_is_valid(part))
+ for_each_user_part(cache, user_part, part_id) {
+ if (!ocf_user_part_is_valid(user_part))
continue;
result = visitor(cache, part_id, cntx);
diff --git a/src/ocf_lru.c b/src/ocf_lru.c
new file mode 100644
index 0000000..6cc298f
--- /dev/null
+++ b/src/ocf_lru.c
@@ -0,0 +1,1055 @@
+/*
+ * Copyright(c) 2012-2021 Intel Corporation
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
+#include "ocf_space.h"
+#include "ocf_lru.h"
+#include "../utils/utils_cleaner.h"
+#include "../utils/utils_cache_line.h"
+#include "../concurrency/ocf_concurrency.h"
+#include "../mngt/ocf_mngt_common.h"
+#include "../engine/engine_zero.h"
+#include "../ocf_cache_priv.h"
+#include "../ocf_request.h"
+#include "../engine/engine_common.h"
+
+static const ocf_cache_line_t end_marker = (ocf_cache_line_t)-1;
+
+/* Adds the given collision_index to the _head_ of the LRU list */
+static void add_lru_head(ocf_cache_t cache,
+ struct ocf_lru_list *list,
+ unsigned int collision_index)
+
+{
+ struct ocf_lru_meta *node;
+ unsigned int curr_head_index;
+
+ ENV_BUG_ON(collision_index == end_marker);
+
+ node = ocf_metadata_get_lru(cache, collision_index);
+ node->hot = false;
+
+ /* First node to be added/ */
+ if (!list->num_nodes) {
+ list->head = collision_index;
+ list->tail = collision_index;
+
+ node->next = end_marker;
+ node->prev = end_marker;
+
+ list->num_nodes = 1;
+ } else {
+ struct ocf_lru_meta *curr_head;
+
+ /* Not the first node to be added. */
+ curr_head_index = list->head;
+
+ ENV_BUG_ON(curr_head_index == end_marker);
+
+ curr_head = ocf_metadata_get_lru(cache, curr_head_index);
+
+ node->next = curr_head_index;
+ node->prev = end_marker;
+ curr_head->prev = collision_index;
+ if (list->track_hot) {
+ node->hot = true;
+ if (!curr_head->hot)
+ list->last_hot = collision_index;
+ ++list->num_hot;
+ }
+
+ list->head = collision_index;
+
+ ++list->num_nodes;
+ }
+}
+
+/* Deletes the node with the given collision_index from the lru list */
+static void remove_lru_list(ocf_cache_t cache,
+ struct ocf_lru_list *list,
+ unsigned int collision_index)
+{
+ int is_head = 0, is_tail = 0;
+ uint32_t prev_lru_node, next_lru_node;
+ struct ocf_lru_meta *node;
+
+ ENV_BUG_ON(collision_index == end_marker);
+
+ node = ocf_metadata_get_lru(cache, collision_index);
+
+ is_head = (list->head == collision_index);
+ is_tail = (list->tail == collision_index);
+
+ if (node->hot)
+ --list->num_hot;
+
+ /* Set prev and next (even if not existent) */
+ next_lru_node = node->next;
+ prev_lru_node = node->prev;
+
+ /* Case 1: If we are head AND tail, there is only one node.
+ * So unlink node and set that there is no node left in the list.
+ */
+ if (is_head && is_tail) {
+ node->next = end_marker;
+ node->prev = end_marker;
+
+ list->head = end_marker;
+ list->tail = end_marker;
+ list->last_hot = end_marker;
+ ENV_BUG_ON(list->num_hot != 0);
+ }
+
+ /* Case 2: else if this collision_index is LRU head, but not tail,
+ * update head and return
+ */
+ else if (is_head) {
+ struct ocf_lru_meta *next_node;
+
+ ENV_BUG_ON(next_lru_node == end_marker);
+
+ next_node = ocf_metadata_get_lru(cache, next_lru_node);
+
+ if (list->last_hot == collision_index) {
+ ENV_BUG_ON(list->num_hot != 0);
+ list->last_hot = end_marker;
+ }
+
+ list->head = next_lru_node;
+
+ node->next = end_marker;
+ next_node->prev = end_marker;
+ }
+
+ /* Case 3: else if this collision_index is LRU tail, but not head,
+ * update tail and return
+ */
+ else if (is_tail) {
+ struct ocf_lru_meta *prev_node;
+
+ ENV_BUG_ON(prev_lru_node == end_marker);
+
+ list->tail = prev_lru_node;
+
+ prev_node = ocf_metadata_get_lru(cache, prev_lru_node);
+
+ node->prev = end_marker;
+ prev_node->next = end_marker;
+ }
+
+ /* Case 4: else this collision_index is a middle node. There is no
+ * change to the head and the tail pointers.
+ */
+ else {
+ struct ocf_lru_meta *prev_node;
+ struct ocf_lru_meta *next_node;
+
+ ENV_BUG_ON(next_lru_node == end_marker);
+ ENV_BUG_ON(prev_lru_node == end_marker);
+
+ next_node = ocf_metadata_get_lru(cache, next_lru_node);
+ prev_node = ocf_metadata_get_lru(cache, prev_lru_node);
+
+ if (list->last_hot == collision_index) {
+ ENV_BUG_ON(list->num_hot == 0);
+ list->last_hot = prev_lru_node;
+ }
+
+ /* Update prev and next nodes */
+ prev_node->next = node->next;
+ next_node->prev = node->prev;
+
+ /* Update the given node */
+ node->next = end_marker;
+ node->prev = end_marker;
+ }
+
+ node->hot = false;
+ --list->num_nodes;
+}
+
+/* Increase / decrease number of hot elements to achieve target count.
+ * Asssumes that the list has hot element clustered together at the
+ * head of the list.
+ */
+static void balance_lru_list(ocf_cache_t cache,
+ struct ocf_lru_list *list)
+{
+ unsigned target_hot_count = list->num_nodes / OCF_LRU_HOT_RATIO;
+ struct ocf_lru_meta *node;
+
+ if (!list->track_hot)
+ return;
+
+ if (target_hot_count == list->num_hot)
+ return;
+
+ if (list->num_hot == 0) {
+ node = ocf_metadata_get_lru(cache, list->head);
+ list->last_hot = list->head;
+ list->num_hot = 1;
+ node->hot = 1;
+ return;
+ }
+
+ ENV_BUG_ON(list->last_hot == end_marker);
+ node = ocf_metadata_get_lru(cache, list->last_hot);
+
+ if (target_hot_count > list->num_hot) {
+ ++list->num_hot;
+ list->last_hot = node->next;
+ node = ocf_metadata_get_lru(cache, node->next);
+ node->hot = true;
+ } else {
+ if (list->last_hot == list->head) {
+ node->hot = false;
+ list->num_hot = 0;
+ list->last_hot = end_marker;
+ } else {
+ ENV_BUG_ON(node->prev == end_marker);
+ node->hot = false;
+ --list->num_hot;
+ list->last_hot = node->prev;
+ }
+ }
+}
+
+
+/*-- End of LRU functions*/
+
+void ocf_lru_init_cline(ocf_cache_t cache, ocf_cache_line_t cline)
+{
+ struct ocf_lru_meta *node;
+
+ node = ocf_metadata_get_lru(cache, cline);
+
+ node->hot = false;
+ node->prev = end_marker;
+ node->next = end_marker;
+}
+
+static struct ocf_lru_list *ocf_lru_get_list(struct ocf_part *part,
+ uint32_t lru_idx, bool clean)
+{
+ return clean ? &part->runtime->lru[lru_idx].clean :
+ &part->runtime->lru[lru_idx].dirty;
+}
+
+static inline struct ocf_lru_list *lru_get_cline_list(ocf_cache_t cache,
+ ocf_cache_line_t cline)
+{
+ uint32_t lru_list = (cline % OCF_NUM_LRU_LISTS);
+ ocf_part_id_t part_id;
+ struct ocf_part *part;
+
+ part_id = ocf_metadata_get_partition_id(cache, cline);
+
+ ENV_BUG_ON(part_id > OCF_USER_IO_CLASS_MAX);
+ part = &cache->user_parts[part_id].part;
+
+ return ocf_lru_get_list(part, lru_list,
+ !metadata_test_dirty(cache, cline));
+}
+
+static void ocf_lru_move(ocf_cache_t cache, ocf_cache_line_t cline,
+ struct ocf_part *src_part, struct ocf_lru_list *src_list,
+ struct ocf_part *dst_part, struct ocf_lru_list *dst_list)
+{
+ remove_lru_list(cache, src_list, cline);
+ balance_lru_list(cache, src_list);
+ add_lru_head(cache, dst_list, cline);
+ balance_lru_list(cache, dst_list);
+ env_atomic_dec(&src_part->runtime->curr_size);
+ env_atomic_inc(&dst_part->runtime->curr_size);
+ ocf_metadata_set_partition_id(cache, cline, dst_part->id);
+
+}
+
+/* the caller must hold the metadata lock */
+void ocf_lru_rm_cline(ocf_cache_t cache, ocf_cache_line_t cline)
+{
+ struct ocf_lru_list *list, *free;
+ uint32_t lru_list = (cline % OCF_NUM_LRU_LISTS);
+ ocf_part_id_t part_id;
+ struct ocf_part *part;
+
+ part_id = ocf_metadata_get_partition_id(cache, cline);
+ ENV_BUG_ON(part_id > OCF_USER_IO_CLASS_MAX);
+ part = &cache->user_parts[part_id].part;
+
+ OCF_METADATA_LRU_WR_LOCK(cline);
+
+ list = lru_get_cline_list(cache, cline);
+ free = ocf_lru_get_list(&cache->free, lru_list, true);
+ ocf_lru_move(cache, cline, part, list, &cache->free, free);
+
+ OCF_METADATA_LRU_WR_UNLOCK(cline);
+}
+
+static void ocf_lru_repart_locked(ocf_cache_t cache, ocf_cache_line_t cline,
+ struct ocf_part *src_part, struct ocf_part *dst_part)
+{
+ uint32_t lru_list = (cline % OCF_NUM_LRU_LISTS);
+ struct ocf_lru_list *src_list, *dst_list;
+ bool clean;
+
+ clean = !metadata_test_dirty(cache, cline);
+ src_list = ocf_lru_get_list(src_part, lru_list, clean);
+ dst_list = ocf_lru_get_list(dst_part, lru_list, clean);
+
+ ocf_lru_move(cache, cline, src_part, src_list, dst_part, dst_list);
+}
+
+void ocf_lru_repart(ocf_cache_t cache, ocf_cache_line_t cline,
+ struct ocf_part *src_part, struct ocf_part *dst_part)
+{
+ OCF_METADATA_LRU_WR_LOCK(cline);
+ ocf_lru_repart_locked(cache, cline, src_part, dst_part);
+ OCF_METADATA_LRU_WR_UNLOCK(cline);
+}
+
+static inline void lru_iter_init(struct ocf_lru_iter *iter, ocf_cache_t cache,
+ struct ocf_part *part, uint32_t start_lru, bool clean,
+ _lru_hash_locked_pfn hash_locked, struct ocf_request *req)
+{
+ uint32_t i;
+
+ /* entire iterator implementation depends on gcc builtins for
+ bit operations which works on 64 bit integers at most */
+ ENV_BUILD_BUG_ON(OCF_NUM_LRU_LISTS > sizeof(iter->lru_idx) * 8);
+
+ iter->cache = cache;
+ iter->c = ocf_cache_line_concurrency(cache);
+ iter->part = part;
+ /* set iterator value to start_lru - 1 modulo OCF_NUM_LRU_LISTS */
+ iter->lru_idx = (start_lru + OCF_NUM_LRU_LISTS - 1) %
+ OCF_NUM_LRU_LISTS;
+ iter->num_avail_lrus = OCF_NUM_LRU_LISTS;
+ iter->next_avail_lru = ((1ULL << OCF_NUM_LRU_LISTS) - 1);
+ iter->clean = clean;
+ iter->hash_locked = hash_locked;
+ iter->req = req;
+
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++)
+ iter->curr_cline[i] = ocf_lru_get_list(part, i, clean)->tail;
+}
+
+static inline void lru_iter_cleaning_init(struct ocf_lru_iter *iter,
+ ocf_cache_t cache, struct ocf_part *part, uint32_t start_lru)
+{
+ /* Lock cachelines for read, non-exclusive access */
+ lru_iter_init(iter, cache, part, start_lru, false, NULL, NULL);
+}
+
+static inline void lru_iter_eviction_init(struct ocf_lru_iter *iter,
+ ocf_cache_t cache, struct ocf_part *part,
+ uint32_t start_lru, struct ocf_request *req)
+{
+ /* Lock hash buckets for write, cachelines according to user request,
+ * however exclusive cacheline access is needed even in case of read
+ * access. _ocf_lru_evict_hash_locked tells whether given hash bucket
+ * is already locked as part of request hash locking (to avoid attempt
+ * to acquire the same hash bucket lock twice) */
+ lru_iter_init(iter, cache, part, start_lru, true, ocf_req_hash_in_range,
+ req);
+}
+
+
+static inline uint32_t _lru_next_lru(struct ocf_lru_iter *iter)
+{
+ unsigned increment;
+
+ increment = __builtin_ffsll(iter->next_avail_lru);
+ iter->next_avail_lru = ocf_rotate_right(iter->next_avail_lru,
+ increment, OCF_NUM_LRU_LISTS);
+ iter->lru_idx = (iter->lru_idx + increment) % OCF_NUM_LRU_LISTS;
+
+ return iter->lru_idx;
+}
+
+
+
+static inline bool _lru_lru_is_empty(struct ocf_lru_iter *iter)
+{
+ return !(iter->next_avail_lru & (1ULL << (OCF_NUM_LRU_LISTS - 1)));
+}
+
+static inline void _lru_lru_set_empty(struct ocf_lru_iter *iter)
+{
+ iter->next_avail_lru &= ~(1ULL << (OCF_NUM_LRU_LISTS - 1));
+ iter->num_avail_lrus--;
+}
+
+static inline bool _lru_lru_all_empty(struct ocf_lru_iter *iter)
+{
+ return iter->num_avail_lrus == 0;
+}
+
+static bool inline _lru_trylock_hash(struct ocf_lru_iter *iter,
+ ocf_core_id_t core_id, uint64_t core_line)
+{
+ if (iter->hash_locked != NULL && iter->hash_locked(
+ iter->req, core_id, core_line)) {
+ return true;
+ }
+
+ return ocf_hb_cline_naked_trylock_wr(
+ &iter->cache->metadata.lock,
+ core_id, core_line);
+}
+
+static void inline _lru_unlock_hash(struct ocf_lru_iter *iter,
+ ocf_core_id_t core_id, uint64_t core_line)
+{
+ if (iter->hash_locked != NULL && iter->hash_locked(
+ iter->req, core_id, core_line)) {
+ return;
+ }
+
+ ocf_hb_cline_naked_unlock_wr(
+ &iter->cache->metadata.lock,
+ core_id, core_line);
+}
+
+static bool inline _lru_iter_evition_lock(struct ocf_lru_iter *iter,
+ ocf_cache_line_t cache_line,
+ ocf_core_id_t *core_id, uint64_t *core_line)
+
+{
+ struct ocf_request *req = iter->req;
+
+ if (!ocf_cache_line_try_lock_wr(iter->c, cache_line))
+ return false;
+
+ ocf_metadata_get_core_info(iter->cache, cache_line,
+ core_id, core_line);
+
+ /* avoid evicting current request target cachelines */
+ if (*core_id == ocf_core_get_id(req->core) &&
+ *core_line >= req->core_line_first &&
+ *core_line <= req->core_line_last) {
+ ocf_cache_line_unlock_wr(iter->c, cache_line);
+ return false;
+ }
+
+ if (!_lru_trylock_hash(iter, *core_id, *core_line)) {
+ ocf_cache_line_unlock_wr(iter->c, cache_line);
+ return false;
+ }
+
+ if (ocf_cache_line_are_waiters(iter->c, cache_line)) {
+ _lru_unlock_hash(iter, *core_id, *core_line);
+ ocf_cache_line_unlock_wr(iter->c, cache_line);
+ return false;
+ }
+
+ return true;
+}
+
+/* Get next clean cacheline from tail of lru lists. Caller must not hold any
+ * lru list lock.
+ * - returned cacheline is write locked
+ * - returned cacheline has the corresponding metadata hash bucket write locked
+ * - cacheline is moved to the head of destination partition lru list before
+ * being returned.
+ * All this is packed into a single function to lock LRU list once per each
+ * replaced cacheline.
+ **/
+static inline ocf_cache_line_t lru_iter_eviction_next(struct ocf_lru_iter *iter,
+ struct ocf_part *dst_part, ocf_core_id_t *core_id,
+ uint64_t *core_line)
+{
+ uint32_t curr_lru;
+ ocf_cache_line_t cline;
+ ocf_cache_t cache = iter->cache;
+ struct ocf_part *part = iter->part;
+ struct ocf_lru_list *list;
+
+ do {
+ curr_lru = _lru_next_lru(iter);
+
+ ocf_metadata_lru_wr_lock(&cache->metadata.lock, curr_lru);
+
+ list = ocf_lru_get_list(part, curr_lru, iter->clean);
+
+ cline = list->tail;
+ while (cline != end_marker && !_lru_iter_evition_lock(iter,
+ cline, core_id, core_line)) {
+ cline = ocf_metadata_get_lru(iter->cache, cline)->prev;
+ }
+
+ if (cline != end_marker) {
+ if (dst_part != part) {
+ ocf_lru_repart_locked(cache, cline, part,
+ dst_part);
+ } else {
+ remove_lru_list(cache, list, cline);
+ add_lru_head(cache, list, cline);
+ balance_lru_list(cache, list);
+ }
+ }
+
+ ocf_metadata_lru_wr_unlock(&cache->metadata.lock,
+ curr_lru);
+
+ if (cline == end_marker && !_lru_lru_is_empty(iter)) {
+ /* mark list as empty */
+ _lru_lru_set_empty(iter);
+ }
+ } while (cline == end_marker && !_lru_lru_all_empty(iter));
+
+ return cline;
+}
+
+/* Get next clean cacheline from tail of free lru lists. Caller must not hold any
+ * lru list lock.
+ * - returned cacheline is write locked
+ * - cacheline is moved to the head of destination partition lru list before
+ * being returned.
+ * All this is packed into a single function to lock LRU list once per each
+ * replaced cacheline.
+ **/
+static inline ocf_cache_line_t lru_iter_free_next(struct ocf_lru_iter *iter,
+ struct ocf_part *dst_part)
+{
+ uint32_t curr_lru;
+ ocf_cache_line_t cline;
+ ocf_cache_t cache = iter->cache;
+ struct ocf_part *free = iter->part;
+ struct ocf_lru_list *list;
+
+ do {
+ curr_lru = _lru_next_lru(iter);
+
+ ocf_metadata_lru_wr_lock(&cache->metadata.lock, curr_lru);
+
+ list = ocf_lru_get_list(free, curr_lru, true);
+
+ cline = list->tail;
+ while (cline != end_marker && !ocf_cache_line_try_lock_wr(
+ iter->c, cline)) {
+ cline = ocf_metadata_get_lru(iter->cache, cline)->prev;
+ }
+
+ if (cline != end_marker) {
+ ocf_lru_repart_locked(cache, cline, free, dst_part);
+ }
+
+ ocf_metadata_lru_wr_unlock(&cache->metadata.lock,
+ curr_lru);
+
+ if (cline == end_marker && !_lru_lru_is_empty(iter)) {
+ /* mark list as empty */
+ _lru_lru_set_empty(iter);
+ }
+ } while (cline == end_marker && !_lru_lru_all_empty(iter));
+
+ return cline;
+}
+
+/* Get next dirty cacheline from tail of lru lists. Caller must hold all
+ * lru list locks during entire iteration proces. Returned cacheline
+ * is read or write locked, depending on iter->write_lock */
+static inline ocf_cache_line_t lru_iter_cleaning_next(struct ocf_lru_iter *iter)
+{
+ uint32_t curr_lru;
+ ocf_cache_line_t cline;
+
+ do {
+ curr_lru = _lru_next_lru(iter);
+ cline = iter->curr_cline[curr_lru];
+
+ while (cline != end_marker && ! ocf_cache_line_try_lock_rd(
+ iter->c, cline)) {
+ cline = ocf_metadata_get_lru(iter->cache, cline)->prev;
+ }
+ if (cline != end_marker) {
+ iter->curr_cline[curr_lru] =
+ ocf_metadata_get_lru(iter->cache , cline)->prev;
+ }
+
+ if (cline == end_marker && !_lru_lru_is_empty(iter)) {
+ /* mark list as empty */
+ _lru_lru_set_empty(iter);
+ }
+ } while (cline == end_marker && !_lru_lru_all_empty(iter));
+
+ return cline;
+}
+
+static void ocf_lru_clean_end(void *private_data, int error)
+{
+ struct ocf_part_cleaning_ctx *ctx = private_data;
+ unsigned i;
+
+ for (i = 0; i < OCF_EVICTION_CLEAN_SIZE; i++) {
+ if (ctx->cline[i] != end_marker)
+ ocf_cache_line_unlock_rd(ctx->cache->device->concurrency
+ .cache_line, ctx->cline[i]);
+ }
+
+ ocf_refcnt_dec(&ctx->counter);
+}
+
+static int ocf_lru_clean_get(ocf_cache_t cache, void *getter_context,
+ uint32_t idx, ocf_cache_line_t *line)
+{
+ struct ocf_part_cleaning_ctx *ctx = getter_context;
+
+ if (ctx->cline[idx] == end_marker)
+ return -1;
+
+ *line = ctx->cline[idx];
+
+ return 0;
+}
+
+void ocf_lru_clean(ocf_cache_t cache, struct ocf_user_part *user_part,
+ ocf_queue_t io_queue, uint32_t count)
+{
+ struct ocf_part_cleaning_ctx *ctx = &user_part->cleaning;
+ struct ocf_cleaner_attribs attribs = {
+ .lock_cacheline = false,
+ .lock_metadata = true,
+ .do_sort = true,
+
+ .cmpl_context = ctx,
+ .cmpl_fn = ocf_lru_clean_end,
+
+ .getter = ocf_lru_clean_get,
+ .getter_context = ctx,
+
+ .count = min(count, OCF_EVICTION_CLEAN_SIZE),
+
+ .io_queue = io_queue
+ };
+ ocf_cache_line_t *cline = ctx->cline;
+ struct ocf_lru_iter iter;
+ unsigned lru_idx;
+ int cnt;
+ unsigned i;
+ unsigned lock_idx;
+
+ if (ocf_mngt_cache_is_locked(cache))
+ return;
+ cnt = ocf_refcnt_inc(&ctx->counter);
+ if (!cnt) {
+ /* cleaner disabled by management operation */
+ return;
+ }
+
+ if (cnt > 1) {
+ /* cleaning already running for this partition */
+ ocf_refcnt_dec(&ctx->counter);
+ return;
+ }
+
+ ctx->cache = cache;
+ lru_idx = io_queue->eviction_idx++ % OCF_NUM_LRU_LISTS;
+
+ lock_idx = ocf_metadata_concurrency_next_idx(io_queue);
+ ocf_metadata_start_shared_access(&cache->metadata.lock, lock_idx);
+
+ OCF_METADATA_LRU_WR_LOCK_ALL();
+
+ lru_iter_cleaning_init(&iter, cache, &user_part->part, lru_idx);
+ i = 0;
+ while (i < OCF_EVICTION_CLEAN_SIZE) {
+ cline[i] = lru_iter_cleaning_next(&iter);
+ if (cline[i] == end_marker)
+ break;
+ i++;
+ }
+ while (i < OCF_EVICTION_CLEAN_SIZE)
+ cline[i++] = end_marker;
+
+ OCF_METADATA_LRU_WR_UNLOCK_ALL();
+
+ ocf_metadata_end_shared_access(&cache->metadata.lock, lock_idx);
+
+ ocf_cleaner_fire(cache, &attribs);
+}
+
+bool ocf_lru_can_evict(ocf_cache_t cache)
+{
+ if (env_atomic_read(&cache->pending_eviction_clines) >=
+ OCF_PENDING_EVICTION_LIMIT) {
+ return false;
+ }
+
+ return true;
+}
+
+static void ocf_lru_invalidate(ocf_cache_t cache, ocf_cache_line_t cline,
+ ocf_core_id_t core_id, ocf_part_id_t part_id)
+{
+ ocf_core_t core;
+
+ ocf_metadata_start_collision_shared_access(
+ cache, cline);
+ metadata_clear_valid_sec(cache, cline, 0,
+ ocf_line_end_sector(cache));
+ ocf_metadata_remove_from_collision(cache, cline, part_id);
+ ocf_metadata_end_collision_shared_access(
+ cache, cline);
+
+ core = ocf_cache_get_core(cache, core_id);
+ env_atomic_dec(&core->runtime_meta->cached_clines);
+ env_atomic_dec(&core->runtime_meta->
+ part_counters[part_id].cached_clines);
+}
+
+/* Assign cachelines from src_part to the request req. src_part is either
+ * user partition (if inserted in the cache) or freelist partition. In case
+ * of user partition mapped cachelines are invalidated (evicted from the cache)
+ * before remaping.
+ * NOTE: the caller must hold the metadata read lock and hash bucket write
+ * lock for the entire request LBA range.
+ * NOTE: all cachelines assigned to the request in this function are marked
+ * as LOOKUP_REMAPPED and are write locked.
+ */
+uint32_t ocf_lru_req_clines(struct ocf_request *req,
+ struct ocf_part *src_part, uint32_t cline_no)
+{
+ struct ocf_alock* alock;
+ struct ocf_lru_iter iter;
+ uint32_t i;
+ ocf_cache_line_t cline;
+ uint64_t core_line;
+ ocf_core_id_t core_id;
+ ocf_cache_t cache = req->cache;
+ unsigned lru_idx;
+ unsigned req_idx = 0;
+ struct ocf_part *dst_part;
+
+
+ if (cline_no == 0)
+ return 0;
+
+ if (unlikely(ocf_engine_unmapped_count(req) < cline_no)) {
+ ocf_cache_log(req->cache, log_err, "Not enough space in"
+ "request: unmapped %u, requested %u",
+ ocf_engine_unmapped_count(req),
+ cline_no);
+ ENV_BUG();
+ }
+
+ ENV_BUG_ON(req->part_id == PARTITION_FREELIST);
+ dst_part = &cache->user_parts[req->part_id].part;
+
+ lru_idx = req->io_queue->eviction_idx++ % OCF_NUM_LRU_LISTS;
+
+ lru_iter_eviction_init(&iter, cache, src_part, lru_idx, req);
+
+ i = 0;
+ while (i < cline_no) {
+ if (!ocf_lru_can_evict(cache))
+ break;
+
+ if (src_part->id != PARTITION_FREELIST) {
+ cline = lru_iter_eviction_next(&iter, dst_part, &core_id,
+ &core_line);
+ } else {
+ cline = lru_iter_free_next(&iter, dst_part);
+ }
+
+ if (cline == end_marker)
+ break;
+
+ ENV_BUG_ON(metadata_test_dirty(cache, cline));
+
+ /* TODO: if atomic mode is restored, need to zero metadata
+ * before proceeding with cleaning (see version <= 20.12) */
+
+ /* find next unmapped cacheline in request */
+ while (req_idx + 1 < req->core_line_count &&
+ req->map[req_idx].status != LOOKUP_MISS) {
+ req_idx++;
+ }
+
+ ENV_BUG_ON(req->map[req_idx].status != LOOKUP_MISS);
+
+ if (src_part->id != PARTITION_FREELIST) {
+ ocf_lru_invalidate(cache, cline, core_id, src_part->id);
+ _lru_unlock_hash(&iter, core_id, core_line);
+ }
+
+ ocf_map_cache_line(req, req_idx, cline);
+
+ req->map[req_idx].status = LOOKUP_REMAPPED;
+ ocf_engine_patch_req_info(cache, req, req_idx);
+
+ alock = ocf_cache_line_concurrency(iter.cache);
+ ocf_alock_mark_index_locked(alock, req, req_idx, true);
+ req->alock_rw = OCF_WRITE;
+
+ ++req_idx;
+ ++i;
+ /* Number of cachelines to evict have to match space in the
+ * request */
+ ENV_BUG_ON(req_idx == req->core_line_count && i != cline_no );
+ }
+
+ return i;
+}
+
+/* the caller must hold the metadata lock */
+void ocf_lru_hot_cline(ocf_cache_t cache, ocf_cache_line_t cline)
+{
+ struct ocf_lru_meta *node;
+ struct ocf_lru_list *list;
+ bool hot;
+
+ node = ocf_metadata_get_lru(cache, cline);
+
+ OCF_METADATA_LRU_RD_LOCK(cline);
+ hot = node->hot;
+ OCF_METADATA_LRU_RD_UNLOCK(cline);
+
+ if (hot)
+ return;
+
+ list = lru_get_cline_list(cache, cline);
+
+ OCF_METADATA_LRU_WR_LOCK(cline);
+
+ if (node->next != end_marker ||
+ node->prev != end_marker ||
+ list->head == cline || list->tail == cline) {
+ remove_lru_list(cache, list, cline);
+ }
+
+ /* Update LRU */
+ add_lru_head(cache, list, cline);
+ balance_lru_list(cache, list);
+
+ OCF_METADATA_LRU_WR_UNLOCK(cline);
+}
+
+static inline void _lru_init(struct ocf_lru_list *list, bool track_hot)
+{
+ list->num_nodes = 0;
+ list->head = end_marker;
+ list->tail = end_marker;
+ list->num_hot = 0;
+ list->last_hot = end_marker;
+ list->track_hot = track_hot;
+}
+
+void ocf_lru_init(ocf_cache_t cache, struct ocf_part *part)
+{
+ struct ocf_lru_list *clean_list;
+ struct ocf_lru_list *dirty_list;
+ uint32_t i;
+
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++) {
+ clean_list = ocf_lru_get_list(part, i, true);
+ dirty_list = ocf_lru_get_list(part, i, false);
+
+ if (part->id == PARTITION_FREELIST) {
+ _lru_init(clean_list, false);
+ } else {
+ _lru_init(clean_list, true);
+ _lru_init(dirty_list, true);
+ }
+ }
+
+ env_atomic_set(&part->runtime->curr_size, 0);
+}
+
+void ocf_lru_clean_cline(ocf_cache_t cache, struct ocf_part *part,
+ ocf_cache_line_t cline)
+{
+ uint32_t lru_list = (cline % OCF_NUM_LRU_LISTS);
+ struct ocf_lru_list *clean_list;
+ struct ocf_lru_list *dirty_list;
+
+ clean_list = ocf_lru_get_list(part, lru_list, true);
+ dirty_list = ocf_lru_get_list(part, lru_list, false);
+
+ OCF_METADATA_LRU_WR_LOCK(cline);
+ remove_lru_list(cache, dirty_list, cline);
+ balance_lru_list(cache, dirty_list);
+ add_lru_head(cache, clean_list, cline);
+ balance_lru_list(cache, clean_list);
+ OCF_METADATA_LRU_WR_UNLOCK(cline);
+}
+
+void ocf_lru_dirty_cline(ocf_cache_t cache, struct ocf_part *part,
+ ocf_cache_line_t cline)
+{
+ uint32_t lru_list = (cline % OCF_NUM_LRU_LISTS);
+ struct ocf_lru_list *clean_list;
+ struct ocf_lru_list *dirty_list;
+
+ clean_list = ocf_lru_get_list(part, lru_list, true);
+ dirty_list = ocf_lru_get_list(part, lru_list, false);
+
+ OCF_METADATA_LRU_WR_LOCK(cline);
+ remove_lru_list(cache, clean_list, cline);
+ balance_lru_list(cache, clean_list);
+ add_lru_head(cache, dirty_list, cline);
+ balance_lru_list(cache, dirty_list);
+ OCF_METADATA_LRU_WR_UNLOCK(cline);
+}
+
+static ocf_cache_line_t next_phys_invalid(ocf_cache_t cache,
+ ocf_cache_line_t phys)
+{
+ ocf_cache_line_t lg;
+ ocf_cache_line_t collision_table_entries =
+ ocf_metadata_collision_table_entries(cache);
+
+ if (phys == collision_table_entries)
+ return collision_table_entries;
+
+ lg = ocf_metadata_map_phy2lg(cache, phys);
+ while (metadata_test_valid_any(cache, lg) &&
+ phys + 1 < collision_table_entries) {
+ ++phys;
+
+ if (phys == collision_table_entries)
+ break;
+
+ lg = ocf_metadata_map_phy2lg(cache, phys);
+ }
+
+ return phys;
+}
+
+/* put invalid cachelines on freelist partition lru list */
+void ocf_lru_populate(ocf_cache_t cache, ocf_cache_line_t num_free_clines)
+{
+ ocf_cache_line_t phys, cline;
+ ocf_cache_line_t collision_table_entries =
+ ocf_metadata_collision_table_entries(cache);
+ struct ocf_lru_list *list;
+ unsigned lru_list;
+ unsigned i;
+
+ phys = 0;
+ for (i = 0; i < num_free_clines; i++) {
+ /* find first invalid cacheline */
+ phys = next_phys_invalid(cache, phys);
+ ENV_BUG_ON(phys == collision_table_entries);
+ cline = ocf_metadata_map_phy2lg(cache, phys);
+ ++phys;
+
+ ocf_metadata_set_partition_id(cache, cline, PARTITION_FREELIST);
+
+ lru_list = (cline % OCF_NUM_LRU_LISTS);
+ list = ocf_lru_get_list(&cache->free, lru_list, true);
+
+ add_lru_head(cache, list, cline);
+ balance_lru_list(cache, list);
+ }
+
+ /* we should have reached the last invalid cache line */
+ phys = next_phys_invalid(cache, phys);
+ ENV_BUG_ON(phys != collision_table_entries);
+
+ env_atomic_set(&cache->free.runtime->curr_size, num_free_clines);
+}
+
+static bool _is_cache_line_acting(struct ocf_cache *cache,
+ uint32_t cache_line, ocf_core_id_t core_id,
+ uint64_t start_line, uint64_t end_line)
+{
+ ocf_core_id_t tmp_core_id;
+ uint64_t core_line;
+
+ ocf_metadata_get_core_info(cache, cache_line,
+ &tmp_core_id, &core_line);
+
+ if (core_id != OCF_CORE_ID_INVALID) {
+ if (core_id != tmp_core_id)
+ return false;
+
+ if (core_line < start_line || core_line > end_line)
+ return false;
+
+ } else if (tmp_core_id == OCF_CORE_ID_INVALID) {
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * Iterates over cache lines that belong to the core device with
+ * core ID = core_id whose core byte addresses are in the range
+ * [start_byte, end_byte] and applies actor(cache, cache_line) to all
+ * matching cache lines
+ *
+ * set partition_id to PARTITION_UNSPECIFIED to not care about partition_id
+ *
+ * global metadata write lock must be held before calling this function
+ */
+int ocf_metadata_actor(struct ocf_cache *cache,
+ ocf_part_id_t part_id, ocf_core_id_t core_id,
+ uint64_t start_byte, uint64_t end_byte,
+ ocf_metadata_actor_t actor)
+{
+ uint32_t step = 0;
+ uint64_t start_line, end_line;
+ int ret = 0;
+ struct ocf_alock *c = ocf_cache_line_concurrency(cache);
+ int clean;
+ struct ocf_lru_list *list;
+ struct ocf_part *part;
+ unsigned i, cline;
+ struct ocf_lru_meta *node;
+
+ start_line = ocf_bytes_2_lines(cache, start_byte);
+ end_line = ocf_bytes_2_lines(cache, end_byte);
+
+ if (part_id == PARTITION_UNSPECIFIED) {
+ for (cline = 0; cline < cache->device->collision_table_entries;
+ ++cline) {
+ if (_is_cache_line_acting(cache, cline, core_id,
+ start_line, end_line)) {
+ if (ocf_cache_line_is_used(c, cline))
+ ret = -OCF_ERR_AGAIN;
+ else
+ actor(cache, cline);
+ }
+
+ OCF_COND_RESCHED_DEFAULT(step);
+ }
+ return ret;
+ }
+
+ ENV_BUG_ON(part_id == PARTITION_FREELIST);
+ part = &cache->user_parts[part_id].part;
+
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++) {
+ for (clean = 0; clean <= 1; clean++) {
+ list = ocf_lru_get_list(part, i, clean);
+
+ cline = list->tail;
+ while (cline != end_marker) {
+ node = ocf_metadata_get_lru(cache, cline);
+ if (!_is_cache_line_acting(cache, cline,
+ core_id, start_line,
+ end_line)) {
+ cline = node->prev;
+ continue;
+ }
+ if (ocf_cache_line_is_used(c, cline))
+ ret = -OCF_ERR_AGAIN;
+ else
+ actor(cache, cline);
+ cline = node->prev;
+ OCF_COND_RESCHED_DEFAULT(step);
+ }
+ }
+ }
+
+ return ret;
+}
+
+uint32_t ocf_lru_num_free(ocf_cache_t cache)
+{
+ return env_atomic_read(&cache->free.runtime->curr_size);
+}
diff --git a/src/ocf_lru.h b/src/ocf_lru.h
new file mode 100644
index 0000000..1179bd1
--- /dev/null
+++ b/src/ocf_lru.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright(c) 2012-2021 Intel Corporation
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+#ifndef __EVICTION_LRU_H__
+#define __EVICTION_LRU_H__
+
+#include "ocf_space.h"
+#include "ocf_lru_structs.h"
+
+struct ocf_part;
+struct ocf_user_part;
+struct ocf_part_runtime;
+struct ocf_part_cleaning_ctx;
+struct ocf_request;
+
+void ocf_lru_init_cline(ocf_cache_t cache, ocf_cache_line_t cline);
+void ocf_lru_rm_cline(struct ocf_cache *cache, ocf_cache_line_t cline);
+bool ocf_lru_can_evict(struct ocf_cache *cache);
+uint32_t ocf_lru_req_clines(struct ocf_request *req,
+ struct ocf_part *src_part, uint32_t cline_no);
+void ocf_lru_hot_cline(struct ocf_cache *cache, ocf_cache_line_t cline);
+void ocf_lru_init(struct ocf_cache *cache, struct ocf_part *part);
+void ocf_lru_dirty_cline(struct ocf_cache *cache, struct ocf_part *part,
+ ocf_cache_line_t cline);
+void ocf_lru_clean_cline(struct ocf_cache *cache, struct ocf_part *part,
+ ocf_cache_line_t cline);
+void ocf_lru_clean(ocf_cache_t cache, struct ocf_user_part *user_part,
+ ocf_queue_t io_queue, uint32_t count);
+void ocf_lru_repart(ocf_cache_t cache, ocf_cache_line_t cline,
+ struct ocf_part *src_upart, struct ocf_part *dst_upart);
+uint32_t ocf_lru_num_free(ocf_cache_t cache);
+void ocf_lru_populate(ocf_cache_t cache, ocf_cache_line_t num_free_clines);
+
+#endif
diff --git a/src/eviction/lru_structs.h b/src/ocf_lru_structs.h
similarity index 87%
rename from src/eviction/lru_structs.h
rename to src/ocf_lru_structs.h
index 87d47e7..c153d26 100644
--- a/src/eviction/lru_structs.h
+++ b/src/ocf_lru_structs.h
@@ -6,7 +6,7 @@
#define __EVICTION_LRU_STRUCTS_H__
-struct lru_eviction_policy_meta {
+struct ocf_lru_meta {
uint32_t prev;
uint32_t next;
uint8_t hot;
@@ -18,9 +18,10 @@ struct ocf_lru_list {
uint32_t tail;
uint32_t num_hot;
uint32_t last_hot;
+ bool track_hot;
};
-struct lru_eviction_policy {
+struct ocf_lru_part_meta {
struct ocf_lru_list clean;
struct ocf_lru_list dirty;
};
diff --git a/src/ocf_request.h b/src/ocf_request.h
index 6188ece..8efdfb5 100644
--- a/src/ocf_request.h
+++ b/src/ocf_request.h
@@ -33,7 +33,7 @@ struct ocf_req_info {
uint32_t mapping_error : 1;
/*!< Core lines in this request were not mapped into cache */
- uint32_t clean_eviction : 1;
+ uint32_t cleaning_required : 1;
/*!< Eviction failed, need to request cleaning */
uint32_t core_error : 1;
@@ -403,14 +403,14 @@ static inline bool ocf_req_test_mapping_error(struct ocf_request *req)
return req->info.mapping_error;
}
-static inline void ocf_req_set_clean_eviction(struct ocf_request *req)
+static inline void ocf_req_set_cleaning_required(struct ocf_request *req)
{
- req->info.clean_eviction = true;
+ req->info.cleaning_required = true;
}
-static inline bool ocf_req_test_clean_eviction(struct ocf_request *req)
+static inline bool ocf_req_is_cleaning_required(struct ocf_request *req)
{
- return req->info.clean_eviction;
+ return req->info.cleaning_required;
}
/**
diff --git a/src/ocf_seq_cutoff.c b/src/ocf_seq_cutoff.c
index cb7d169..dabf0db 100644
--- a/src/ocf_seq_cutoff.c
+++ b/src/ocf_seq_cutoff.c
@@ -19,8 +19,8 @@ static inline bool ocf_seq_cutoff_is_on(ocf_cache_t cache,
if (!ocf_cache_is_device_attached(cache))
return false;
- return (ocf_freelist_num_free(cache->freelist) <=
- SEQ_CUTOFF_FULL_MARGIN + req->core_line_count);
+ return (ocf_lru_num_free(cache) <= SEQ_CUTOFF_FULL_MARGIN +
+ req->core_line_count);
}
static int ocf_seq_cutoff_stream_cmp(struct ocf_rb_node *n1,
diff --git a/src/eviction/eviction.c b/src/ocf_space.c
similarity index 55%
rename from src/eviction/eviction.c
rename to src/ocf_space.c
index 369d699..878ed33 100644
--- a/src/eviction/eviction.c
+++ b/src/ocf_space.c
@@ -3,31 +3,16 @@
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
-#include "eviction.h"
-#include "ops.h"
-#include "../utils/utils_part.h"
+#include "ocf_space.h"
+#include "../utils/utils_user_part.h"
#include "../engine/engine_common.h"
-struct eviction_policy_ops evict_policy_ops[ocf_eviction_max] = {
- [ocf_eviction_lru] = {
- .init_cline = evp_lru_init_cline,
- .rm_cline = evp_lru_rm_cline,
- .req_clines = evp_lru_req_clines,
- .hot_cline = evp_lru_hot_cline,
- .init_evp = evp_lru_init_evp,
- .dirty_cline = evp_lru_dirty_cline,
- .clean_cline = evp_lru_clean_cline,
- .flush_dirty = evp_lru_clean,
- .name = "lru",
- },
-};
-
static uint32_t ocf_evict_calculate(ocf_cache_t cache,
- struct ocf_user_part *part, uint32_t to_evict)
+ struct ocf_user_part *user_part, uint32_t to_evict)
{
- uint32_t curr_part_size = ocf_part_get_occupancy(part);
- uint32_t min_part_size = ocf_part_get_min_size(cache, part);
+ uint32_t curr_part_size = ocf_part_get_occupancy(&user_part->part);
+ uint32_t min_part_size = ocf_user_part_get_min_size(cache, user_part);
if (curr_part_size <= min_part_size) {
/*
@@ -44,15 +29,12 @@ static uint32_t ocf_evict_calculate(ocf_cache_t cache,
}
static inline uint32_t ocf_evict_part_do(struct ocf_request *req,
- struct ocf_user_part *target_part)
+ struct ocf_user_part *user_part)
{
uint32_t unmapped = ocf_engine_unmapped_count(req);
uint32_t to_evict = 0;
- if (!evp_lru_can_evict(req->cache))
- return 0;
-
- to_evict = ocf_evict_calculate(req->cache, target_part, unmapped);
+ to_evict = ocf_evict_calculate(req->cache, user_part, unmapped);
if (to_evict < unmapped) {
/* cannot evict enough cachelines to map request,
@@ -60,34 +42,31 @@ static inline uint32_t ocf_evict_part_do(struct ocf_request *req,
return 0;
}
- return ocf_eviction_need_space(req->cache, req, target_part, to_evict);
+ return ocf_lru_req_clines(req, &user_part->part, to_evict);
}
-static inline uint32_t ocf_evict_partitions(ocf_cache_t cache,
+static inline uint32_t ocf_evict_user_partitions(ocf_cache_t cache,
struct ocf_request *req, uint32_t evict_cline_no,
bool overflown_only, int16_t max_priority)
{
uint32_t to_evict = 0, evicted = 0;
- struct ocf_user_part *part;
+ struct ocf_user_part *user_part;
ocf_part_id_t part_id;
unsigned overflow_size;
/* For each partition from the lowest priority to highest one */
- for_each_part(cache, part, part_id) {
- if (!ocf_eviction_can_evict(cache))
- goto out;
-
+ for_each_user_part(cache, user_part, part_id) {
/*
* Check stop and continue conditions
*/
- if (max_priority > part->config->priority) {
+ if (max_priority > user_part->config->priority) {
/*
* iterate partition have higher priority,
* do not evict
*/
break;
}
- if (!overflown_only && !part->config->flags.eviction) {
+ if (!overflown_only && !user_part->config->flags.eviction) {
/* If partition is overflown it should be evcited
* even if its pinned
*/
@@ -95,12 +74,12 @@ static inline uint32_t ocf_evict_partitions(ocf_cache_t cache,
}
if (overflown_only) {
- overflow_size = ocf_part_overflow_size(cache, part);
+ overflow_size = ocf_user_part_overflow_size(cache, user_part);
if (overflow_size == 0)
continue;
}
- to_evict = ocf_evict_calculate(cache, part,
+ to_evict = ocf_evict_calculate(cache, user_part,
evict_cline_no - evicted);
if (to_evict == 0) {
/* No cache lines to evict for this partition */
@@ -110,7 +89,7 @@ static inline uint32_t ocf_evict_partitions(ocf_cache_t cache,
if (overflown_only)
to_evict = OCF_MIN(to_evict, overflow_size);
- evicted += ocf_eviction_need_space(cache, req, part, to_evict);
+ evicted += ocf_lru_req_clines(req, &user_part->part, to_evict);
if (evicted >= evict_cline_no) {
/* Evicted requested number of cache line, stop
@@ -124,48 +103,55 @@ out:
return evicted;
}
-static inline uint32_t ocf_evict_do(struct ocf_request *req)
+static inline uint32_t ocf_remap_do(struct ocf_request *req)
{
ocf_cache_t cache = req->cache;
ocf_part_id_t target_part_id = req->part_id;
struct ocf_user_part *target_part = &cache->user_parts[target_part_id];
- uint32_t evict_cline_no = ocf_engine_unmapped_count(req);
- uint32_t evicted;
+ uint32_t remap_cline_no = ocf_engine_unmapped_count(req);
+ uint32_t remapped = 0;
- /* First attempt to evict overflown partitions in order to
+ /* First attempt to map from freelist */
+ if (ocf_lru_num_free(cache) > 0)
+ remapped = ocf_lru_req_clines(req, &cache->free, remap_cline_no);
+
+ if (remapped >= remap_cline_no)
+ return remapped;
+
+ /* Attempt to evict overflown partitions in order to
* achieve configured maximum size. Ignoring partitions
* priority in this case, as overflown partitions should
* free its cachelines regardless of destination partition
* priority. */
-
- evicted = ocf_evict_partitions(cache, req, evict_cline_no,
+ remapped += ocf_evict_user_partitions(cache, req, remap_cline_no,
true, OCF_IO_CLASS_PRIO_PINNED);
- if (evicted >= evict_cline_no)
- return evicted;
+ if (remapped >= remap_cline_no)
+ return remapped;
+
/* Not enough cachelines in overflown partitions. Go through
* partitions with priority <= target partition and attempt
* to evict from those. */
- evict_cline_no -= evicted;
- evicted += ocf_evict_partitions(cache, req, evict_cline_no,
+ remap_cline_no -= remapped;
+ remapped += ocf_evict_user_partitions(cache, req, remap_cline_no,
false, target_part->config->priority);
- return evicted;
+ return remapped;
}
-int space_managment_evict_do(struct ocf_request *req)
+int ocf_space_managment_remap_do(struct ocf_request *req)
{
uint32_t needed = ocf_engine_unmapped_count(req);
- uint32_t evicted;
+ uint32_t remapped;
struct ocf_user_part *req_part = &req->cache->user_parts[req->part_id];
if (ocf_req_part_evict(req)) {
- evicted = ocf_evict_part_do(req, req_part);
+ remapped = ocf_evict_part_do(req, req_part);
} else {
- evicted = ocf_evict_do(req);
+ remapped = ocf_remap_do(req);
}
- if (needed <= evicted)
- return LOOKUP_INSERTED;
+ if (needed <= remapped)
+ return LOOKUP_REMAPPED;
return LOOKUP_MISS;
}
diff --git a/src/ocf_space.h b/src/ocf_space.h
new file mode 100644
index 0000000..51b7fa6
--- /dev/null
+++ b/src/ocf_space.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright(c) 2012-2021 Intel Corporation
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
+#ifndef __LAYER_EVICTION_POLICY_H__
+#define __LAYER_EVICTION_POLICY_H__
+
+#include "ocf/ocf.h"
+#include "ocf_lru.h"
+#include "ocf_lru_structs.h"
+
+#define OCF_PENDING_EVICTION_LIMIT 512UL
+
+#define OCF_NUM_LRU_LISTS 32
+
+struct ocf_part;
+struct ocf_user_part;
+struct ocf_part_runtime;
+struct ocf_part_cleaning_ctx;
+struct ocf_request;
+
+/*
+ * Deallocates space according to eviction priorities.
+ *
+ * @returns:
+ * 'LOOKUP_HIT' if evicted enough cachelines to serve @req
+ * 'LOOKUP_MISS' otherwise
+ */
+int ocf_space_managment_remap_do(struct ocf_request *req);
+
+typedef void (*ocf_metadata_actor_t)(struct ocf_cache *cache,
+ ocf_cache_line_t cache_line);
+
+int ocf_metadata_actor(struct ocf_cache *cache,
+ ocf_part_id_t part_id, ocf_core_id_t core_id,
+ uint64_t start_byte, uint64_t end_byte,
+ ocf_metadata_actor_t actor);
+#endif
diff --git a/src/ocf_stats.c b/src/ocf_stats.c
index 5bb8486..0fa2139 100644
--- a/src/ocf_stats.c
+++ b/src/ocf_stats.c
@@ -7,7 +7,7 @@
#include "ocf_priv.h"
#include "metadata/metadata.h"
#include "engine/cache_engine.h"
-#include "utils/utils_part.h"
+#include "utils/utils_user_part.h"
#include "utils/utils_cache_line.h"
#ifdef OCF_DEBUG_STATS
@@ -195,7 +195,7 @@ void ocf_core_stats_initialize(ocf_core_t core)
ocf_stats_error_init(&exp_obj_stats->cache_errors);
ocf_stats_error_init(&exp_obj_stats->core_errors);
- for (i = 0; i != OCF_IO_CLASS_MAX; i++)
+ for (i = 0; i != OCF_USER_IO_CLASS_MAX; i++)
ocf_stats_part_init(&exp_obj_stats->part_counters[i]);
#ifdef OCF_DEBUG_STATS
@@ -286,7 +286,7 @@ int ocf_core_io_class_get_stats(ocf_core_t core, ocf_part_id_t part_id,
cache = ocf_core_get_cache(core);
- if (!ocf_part_is_valid(&cache->user_parts[part_id]))
+ if (!ocf_user_part_is_valid(&cache->user_parts[part_id]))
return -OCF_ERR_IO_CLASS_NOT_EXIST;
part_stat = &core->counters->part_counters[part_id];
@@ -333,7 +333,7 @@ int ocf_core_get_stats(ocf_core_t core, struct ocf_stats_core *stats)
&core_stats->debug_stats);
#endif
- for (i = 0; i != OCF_IO_CLASS_MAX; i++) {
+ for (i = 0; i != OCF_USER_IO_CLASS_MAX; i++) {
curr = &core_stats->part_counters[i];
accum_req_stats(&stats->read_reqs,
diff --git a/src/ocf_stats_builder.c b/src/ocf_stats_builder.c
index c0d7d2e..6990ea0 100644
--- a/src/ocf_stats_builder.c
+++ b/src/ocf_stats_builder.c
@@ -7,7 +7,7 @@
#include "ocf_priv.h"
#include "metadata/metadata.h"
#include "engine/cache_engine.h"
-#include "utils/utils_part.h"
+#include "utils/utils_user_part.h"
#include "utils/utils_cache_line.h"
#include "utils/utils_stats.h"
diff --git a/src/ocf_stats_priv.h b/src/ocf_stats_priv.h
index 31c0b47..4fb933d 100644
--- a/src/ocf_stats_priv.h
+++ b/src/ocf_stats_priv.h
@@ -176,7 +176,7 @@ struct ocf_counters_core {
struct ocf_counters_error core_errors;
struct ocf_counters_error cache_errors;
- struct ocf_counters_part part_counters[OCF_IO_CLASS_MAX];
+ struct ocf_counters_part part_counters[OCF_USER_IO_CLASS_MAX];
#ifdef OCF_DEBUG_STATS
struct ocf_counters_debug debug_stats;
#endif
diff --git a/src/promotion/nhit/nhit.c b/src/promotion/nhit/nhit.c
index 8705ace..04f0763 100644
--- a/src/promotion/nhit/nhit.c
+++ b/src/promotion/nhit/nhit.c
@@ -222,7 +222,7 @@ bool nhit_req_should_promote(ocf_promotion_policy_t policy,
uint64_t core_line;
uint64_t occupied_cachelines =
ocf_metadata_collision_table_entries(policy->owner) -
- ocf_freelist_num_free(policy->owner->freelist);
+ ocf_lru_num_free(policy->owner);
cfg = (struct nhit_promotion_policy_config*)policy->config;
diff --git a/src/utils/utils_alock.c b/src/utils/utils_alock.c
index 0a25b1b..9d43beb 100644
--- a/src/utils/utils_alock.c
+++ b/src/utils/utils_alock.c
@@ -790,23 +790,6 @@ bool ocf_alock_waitlist_is_empty(struct ocf_alock *alock,
return empty;
}
-/* NOTE: it is caller responsibility to assure that noone acquires
- * a lock in background */
-bool ocf_alock_is_locked_exclusively(struct ocf_alock *alock,
- ocf_cache_line_t entry)
-{
- env_atomic *access = &alock->access[entry];
- int val = env_atomic_read(access);
-
- ENV_BUG_ON(val == OCF_CACHE_LINE_ACCESS_IDLE);
-
- if (!ocf_alock_waitlist_is_empty(alock, entry))
- return false;
-
- return val == OCF_CACHE_LINE_ACCESS_ONE_RD ||
- val == OCF_CACHE_LINE_ACCESS_WR;
-}
-
uint32_t ocf_alock_waitlist_count(struct ocf_alock *alock)
{
return env_atomic_read(&alock->waiting);
diff --git a/src/utils/utils_alock.h b/src/utils/utils_alock.h
index 2970755..2d3df97 100644
--- a/src/utils/utils_alock.h
+++ b/src/utils/utils_alock.h
@@ -53,9 +53,6 @@ int ocf_alock_lock_wr(struct ocf_alock *alock,
bool ocf_alock_waitlist_is_empty(struct ocf_alock *alock,
ocf_cache_line_t entry);
-bool ocf_alock_is_locked_exclusively(struct ocf_alock *alock,
- ocf_cache_line_t entry);
-
uint32_t ocf_alock_waitlist_count(struct ocf_alock *alock);
size_t ocf_alock_obj_size(void);
diff --git a/src/utils/utils_cache_line.c b/src/utils/utils_cache_line.c
index 0b6a837..8be264e 100644
--- a/src/utils/utils_cache_line.c
+++ b/src/utils/utils_cache_line.c
@@ -102,10 +102,12 @@ void set_cache_line_clean(struct ocf_cache *cache, uint8_t start_bit,
{
ocf_cache_line_t line = req->map[map_idx].coll_idx;
ocf_part_id_t part_id = ocf_metadata_get_partition_id(cache, line);
- struct ocf_user_part *part = &cache->user_parts[part_id];
- uint8_t evp_type = cache->conf_meta->eviction_policy_type;
+ struct ocf_part *part = &cache->user_parts[part_id].part;
bool line_is_clean;
+ ENV_BUG_ON(part_id > OCF_USER_IO_CLASS_MAX);
+ part = &cache->user_parts[part_id].part;
+
if (metadata_clear_dirty_sec_changed(cache, line, start_bit, end_bit,
&line_is_clean)) {
ocf_metadata_flush_mark(cache, req, map_idx, CLEAN, start_bit,
@@ -130,10 +132,7 @@ void set_cache_line_clean(struct ocf_cache *cache, uint8_t start_bit,
*/
env_atomic_dec(&req->core->runtime_meta->
part_counters[part_id].dirty_clines);
-
- if (likely(evict_policy_ops[evp_type].clean_cline))
- evict_policy_ops[evp_type].clean_cline(cache, part, line);
-
+ ocf_lru_clean_cline(cache, part, line);
ocf_purge_cleaning_policy(cache, line);
}
}
@@ -145,10 +144,12 @@ void set_cache_line_dirty(struct ocf_cache *cache, uint8_t start_bit,
{
ocf_cache_line_t line = req->map[map_idx].coll_idx;
ocf_part_id_t part_id = ocf_metadata_get_partition_id(cache, line);
- struct ocf_user_part *part = &cache->user_parts[part_id];
- uint8_t evp_type = cache->conf_meta->eviction_policy_type;
+ struct ocf_part *part;
bool line_was_dirty;
+ ENV_BUG_ON(part_id > OCF_USER_IO_CLASS_MAX);
+ part = &cache->user_parts[part_id].part;
+
if (metadata_set_dirty_sec_changed(cache, line, start_bit, end_bit,
&line_was_dirty)) {
ocf_metadata_flush_mark(cache, req, map_idx, DIRTY, start_bit,
@@ -173,9 +174,7 @@ void set_cache_line_dirty(struct ocf_cache *cache, uint8_t start_bit,
*/
env_atomic_inc(&req->core->runtime_meta->
part_counters[part_id].dirty_clines);
-
- if (likely(evict_policy_ops[evp_type].dirty_cline))
- evict_policy_ops[evp_type].dirty_cline(cache, part, line);
+ ocf_lru_dirty_cline(cache, part, line);
}
}
diff --git a/src/utils/utils_cache_line.h b/src/utils/utils_cache_line.h
index 5c44f21..ec9510b 100644
--- a/src/utils/utils_cache_line.h
+++ b/src/utils/utils_cache_line.h
@@ -8,8 +8,7 @@
#include "../metadata/metadata.h"
#include "../concurrency/ocf_cache_line_concurrency.h"
-#include "../eviction/eviction.h"
-#include "../eviction/ops.h"
+#include "../ocf_space.h"
#include "../engine/cache_engine.h"
#include "../ocf_request.h"
#include "../ocf_def_priv.h"
@@ -180,7 +179,7 @@ static inline void ocf_purge_cleaning_policy(struct ocf_cache *cache,
static inline void ocf_purge_eviction_policy(struct ocf_cache *cache,
ocf_cache_line_t line)
{
- ocf_eviction_purge_cache_line(cache, line);
+ ocf_lru_rm_cline(cache, line);
}
/**
diff --git a/src/utils/utils_cleaner.c b/src/utils/utils_cleaner.c
index 3cc165d..c9e285d 100644
--- a/src/utils/utils_cleaner.c
+++ b/src/utils/utils_cleaner.c
@@ -9,7 +9,7 @@
#include "../concurrency/ocf_concurrency.h"
#include "../ocf_request.h"
#include "utils_cleaner.h"
-#include "utils_part.h"
+#include "utils_user_part.h"
#include "utils_io.h"
#include "utils_cache_line.h"
#include "../ocf_queue_priv.h"
@@ -1052,7 +1052,7 @@ void ocf_cleaner_refcnt_freeze(ocf_cache_t cache)
struct ocf_user_part *curr_part;
ocf_part_id_t part_id;
- for_each_part(cache, curr_part, part_id)
+ for_each_user_part(cache, curr_part, part_id)
ocf_refcnt_freeze(&curr_part->cleaning.counter);
}
@@ -1061,7 +1061,7 @@ void ocf_cleaner_refcnt_unfreeze(ocf_cache_t cache)
struct ocf_user_part *curr_part;
ocf_part_id_t part_id;
- for_each_part(cache, curr_part, part_id)
+ for_each_user_part(cache, curr_part, part_id)
ocf_refcnt_unfreeze(&curr_part->cleaning.counter);
}
@@ -1084,7 +1084,7 @@ void ocf_cleaner_refcnt_register_zero_cb(ocf_cache_t cache,
ctx->cb = cb;
ctx->priv = priv;
- for_each_part(cache, curr_part, part_id) {
+ for_each_user_part(cache, curr_part, part_id) {
env_atomic_inc(&ctx->waiting);
ocf_refcnt_register_zero_cb(&curr_part->cleaning.counter,
ocf_cleaner_refcnt_register_zero_cb_finish, ctx);
diff --git a/src/utils/utils_part.h b/src/utils/utils_part.h
deleted file mode 100644
index 2c2e15f..0000000
--- a/src/utils/utils_part.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright(c) 2012-2021 Intel Corporation
- * SPDX-License-Identifier: BSD-3-Clause-Clear
- */
-
-#ifndef __UTILS_PARTITION_H__
-#define __UTILS_PARTITION_H__
-
-#include "../ocf_request.h"
-#include "../engine/cache_engine.h"
-#include "../engine/engine_common.h"
-#include "../metadata/metadata_partition.h"
-
-void ocf_part_init(struct ocf_cache *cache);
-
-static inline bool ocf_part_is_valid(struct ocf_user_part *part)
-{
- return !!part->config->flags.valid;
-}
-
-static inline void ocf_part_set_prio(struct ocf_cache *cache,
- struct ocf_user_part *part, int16_t prio)
-{
- if (part->config->priority != prio)
- part->config->priority = prio;
-}
-
-static inline int16_t ocf_part_get_prio(struct ocf_cache *cache,
- ocf_part_id_t part_id)
-{
- if (part_id < OCF_IO_CLASS_MAX)
- return cache->user_parts[part_id].config->priority;
-
- return OCF_IO_CLASS_PRIO_LOWEST;
-}
-
-void ocf_part_set_valid(struct ocf_cache *cache, ocf_part_id_t id,
- bool valid);
-
-static inline bool ocf_part_is_added(struct ocf_user_part *part)
-{
- return !!part->config->flags.added;
-}
-
-static inline ocf_part_id_t ocf_part_class2id(ocf_cache_t cache, uint64_t class)
-{
- if (class < OCF_IO_CLASS_MAX)
- if (cache->user_parts[class].config->flags.valid)
- return class;
-
- return PARTITION_DEFAULT;
-}
-
-static inline uint32_t ocf_part_get_occupancy(struct ocf_user_part *part)
-{
- return part->runtime->curr_size;
-}
-
-static inline uint32_t ocf_part_get_min_size(ocf_cache_t cache,
- struct ocf_user_part *part)
-{
- uint64_t ioclass_size;
-
- ioclass_size = (uint64_t)part->config->min_size *
- (uint64_t)cache->conf_meta->cachelines;
-
- ioclass_size /= 100;
-
- return (uint32_t)ioclass_size;
-}
-
-
-static inline uint32_t ocf_part_get_max_size(ocf_cache_t cache,
- struct ocf_user_part *part)
-{
- uint64_t ioclass_size, max_size, cache_size;
-
- max_size = part->config->max_size;
- cache_size = cache->conf_meta->cachelines;
-
- ioclass_size = max_size * cache_size;
- ioclass_size = OCF_DIV_ROUND_UP(ioclass_size, 100);
-
- return (uint32_t)ioclass_size;
-}
-
-void ocf_part_move(struct ocf_request *req);
-
-#define for_each_part(cache, part, id) \
- for_each_lst_entry(&cache->lst_part, part, id, \
- struct ocf_user_part, lst_valid)
-
-static inline void ocf_part_sort(struct ocf_cache *cache)
-{
- ocf_lst_sort(&cache->lst_part);
-}
-
-static inline bool ocf_part_is_enabled(struct ocf_user_part *part)
-{
- return part->config->max_size != 0;
-}
-
-static inline uint32_t ocf_part_overflow_size(struct ocf_cache *cache,
- struct ocf_user_part *part)
-{
- uint32_t part_occupancy = ocf_part_get_occupancy(part);
- uint32_t part_occupancy_limit = ocf_part_get_max_size(cache, part);
-
- if (part_occupancy > part_occupancy_limit)
- return part_occupancy - part_occupancy_limit;
-
- return 0;
-}
-
-static inline bool ocf_part_has_space(struct ocf_request *req)
-{
- struct ocf_user_part *target_part = &req->cache->user_parts[req->part_id];
- uint64_t part_occupancy_limit =
- ocf_part_get_max_size(req->cache, target_part);
- uint64_t needed_cache_lines = ocf_engine_repart_count(req) +
- ocf_engine_unmapped_count(req);
- uint64_t part_occupancy = ocf_part_get_occupancy(target_part);
-
- return (part_occupancy + needed_cache_lines <= part_occupancy_limit);
-}
-
-static inline ocf_cache_mode_t ocf_part_get_cache_mode(ocf_cache_t cache,
- ocf_part_id_t part_id)
-{
- if (part_id < OCF_IO_CLASS_MAX)
- return cache->user_parts[part_id].config->cache_mode;
- return ocf_cache_mode_none;
-}
-
-static inline bool ocf_part_is_prio_valid(int64_t prio)
-{
- switch (prio) {
- case OCF_IO_CLASS_PRIO_HIGHEST ... OCF_IO_CLASS_PRIO_LOWEST:
- case OCF_IO_CLASS_PRIO_PINNED:
- return true;
-
- default:
- return false;
- }
-}
-
-/**
- * routine checks for validity of a partition name.
- *
- * Following condition is checked:
- * - string too long
- * - string containing invalid characters (outside of low ascii)
- * Following condition is NOT cheched:
- * - empty string. (empty string is NOT a valid partition name, but
- * this function returns true on empty string nevertheless).
- *
- * @return returns true if partition name is a valid name
- */
-static inline bool ocf_part_is_name_valid(const char *name)
-{
- uint32_t length = 0;
-
- while (*name) {
- if (*name < ' ' || *name > '~')
- return false;
-
- if (',' == *name || '"' == *name)
- return false;
-
- name++;
- length++;
-
- if (length >= OCF_IO_CLASS_NAME_MAX)
- return false;
- }
-
- return true;
-}
-
-#endif /* __UTILS_PARTITION_H__ */
diff --git a/src/utils/utils_part.c b/src/utils/utils_user_part.c
similarity index 70%
rename from src/utils/utils_part.c
rename to src/utils/utils_user_part.c
index 7507dc1..eadb3c9 100644
--- a/src/utils/utils_part.c
+++ b/src/utils/utils_user_part.c
@@ -8,18 +8,18 @@
#include "../ocf_request.h"
#include "../metadata/metadata.h"
#include "../engine/cache_engine.h"
-#include "../eviction/ops.h"
-#include "utils_part.h"
+#include "../ocf_lru.h"
+#include "utils_user_part.h"
-static struct ocf_lst_entry *ocf_part_lst_getter_valid(
+static struct ocf_lst_entry *ocf_user_part_lst_getter_valid(
struct ocf_cache *cache, ocf_cache_line_t idx)
{
- ENV_BUG_ON(idx > OCF_IO_CLASS_MAX);
+ ENV_BUG_ON(idx > OCF_USER_IO_CLASS_MAX);
return &cache->user_parts[idx].lst_valid;
}
-static int ocf_part_lst_cmp_valid(struct ocf_cache *cache,
+static int ocf_user_part_lst_cmp_valid(struct ocf_cache *cache,
struct ocf_lst_entry *e1, struct ocf_lst_entry *e2)
{
struct ocf_user_part *p1 = container_of(e1, struct ocf_user_part,
@@ -27,10 +27,11 @@ static int ocf_part_lst_cmp_valid(struct ocf_cache *cache,
struct ocf_user_part *p2 = container_of(e2, struct ocf_user_part,
lst_valid);
size_t p1_size = ocf_cache_is_device_attached(cache) ?
- p1->runtime->curr_size : 0;
+ env_atomic_read(&p1->part.runtime->curr_size)
+ : 0;
size_t p2_size = ocf_cache_is_device_attached(cache) ?
- p2->runtime->curr_size : 0;
-
+ env_atomic_read(&p2->part.runtime->curr_size)
+ : 0;
int v1 = p1->config->priority;
int v2 = p2->config->priority;
@@ -79,13 +80,19 @@ static int ocf_part_lst_cmp_valid(struct ocf_cache *cache,
return v2 - v1;
}
-void ocf_part_init(struct ocf_cache *cache)
+void ocf_user_part_init(struct ocf_cache *cache)
{
- ocf_lst_init(cache, &cache->lst_part, OCF_IO_CLASS_MAX,
- ocf_part_lst_getter_valid, ocf_part_lst_cmp_valid);
+ unsigned i;
+
+ ocf_lst_init(cache, &cache->user_part_list, OCF_USER_IO_CLASS_MAX,
+ ocf_user_part_lst_getter_valid,
+ ocf_user_part_lst_cmp_valid);
+
+ for (i = 0; i < OCF_USER_IO_CLASS_MAX + 1; i++)
+ cache->user_parts[i].part.id = i;
}
-void ocf_part_move(struct ocf_request *req)
+void ocf_user_part_move(struct ocf_request *req)
{
struct ocf_cache *cache = req->cache;
struct ocf_map_info *entry;
@@ -104,11 +111,11 @@ void ocf_part_move(struct ocf_request *req)
}
/* Moving cachelines to another partition is needed only
- * for those already mapped before this request, which
- * indicates either HIT or REMAPPED.
+ * for those already mapped before this request and remapped
+ * cachelines are assigned to target partition during eviction.
+ * So only hit cachelines are interesting.
*/
- if (entry->status != LOOKUP_HIT &&
- entry->status != LOOKUP_REMAPPED) {
+ if (entry->status != LOOKUP_HIT) {
/* No HIT */
continue;
}
@@ -117,8 +124,8 @@ void ocf_part_move(struct ocf_request *req)
id_old = ocf_metadata_get_partition_id(cache, line);
id_new = req->part_id;
- ENV_BUG_ON(id_old >= OCF_IO_CLASS_MAX ||
- id_new >= OCF_IO_CLASS_MAX);
+ ENV_BUG_ON(id_old >= OCF_USER_IO_CLASS_MAX ||
+ id_new >= OCF_USER_IO_CLASS_MAX);
if (id_old == id_new) {
/* Partition of the request and cache line is the same,
@@ -127,9 +134,6 @@ void ocf_part_move(struct ocf_request *req)
continue;
}
- /* Remove from old eviction */
- ocf_eviction_purge_cache_line(cache, line);
-
if (metadata_test_dirty(cache, line)) {
/*
* Remove cline from cleaning - this if for ioclass
@@ -142,13 +146,8 @@ void ocf_part_move(struct ocf_request *req)
purge_cache_block(cache, line);
}
- /* Let's change partition */
- ocf_metadata_remove_from_partition(cache, id_old, line);
- ocf_metadata_add_to_partition(cache, id_new, line);
-
- /* Add to new eviction */
- ocf_eviction_init_cache_line(cache, line);
- ocf_eviction_set_hot_cache_line(cache, line);
+ ocf_lru_repart(cache, line, &cache->user_parts[id_old].part,
+ &cache->user_parts[id_new].part);
/* Check if cache line is dirty. If yes then need to change
* cleaning policy and update partition dirty clines
@@ -175,22 +174,23 @@ void ocf_part_move(struct ocf_request *req)
}
}
-void ocf_part_set_valid(struct ocf_cache *cache, ocf_part_id_t id,
+void ocf_user_part_set_valid(struct ocf_cache *cache, ocf_part_id_t id,
bool valid)
{
- struct ocf_user_part *part = &cache->user_parts[id];
+ struct ocf_user_part *user_part = &cache->user_parts[id];
- if (valid ^ part->config->flags.valid) {
+ if (valid ^ user_part->config->flags.valid) {
if (valid) {
- part->config->flags.valid = true;
+ user_part->config->flags.valid = true;
cache->conf_meta->valid_parts_no++;
} else {
- part->config->flags.valid = false;
+ user_part->config->flags.valid = false;
cache->conf_meta->valid_parts_no--;
- part->config->priority = OCF_IO_CLASS_PRIO_LOWEST;
- part->config->min_size = 0;
- part->config->max_size = PARTITION_SIZE_MAX;
- ENV_BUG_ON(env_strncpy(part->config->name, sizeof(part->config->name),
+ user_part->config->priority = OCF_IO_CLASS_PRIO_LOWEST;
+ user_part->config->min_size = 0;
+ user_part->config->max_size = PARTITION_SIZE_MAX;
+ ENV_BUG_ON(env_strncpy(user_part->config->name,
+ sizeof(user_part->config->name),
"Inactive", 9));
}
}
diff --git a/src/utils/utils_user_part.h b/src/utils/utils_user_part.h
new file mode 100644
index 0000000..a64a8a4
--- /dev/null
+++ b/src/utils/utils_user_part.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright(c) 2012-2021 Intel Corporation
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
+#ifndef __UTILS_PARTITION_H__
+#define __UTILS_PARTITION_H__
+
+#include "../ocf_request.h"
+#include "../engine/cache_engine.h"
+#include "../engine/engine_common.h"
+#include "../metadata/metadata_partition.h"
+
+void ocf_user_part_init(struct ocf_cache *cache);
+
+static inline bool ocf_user_part_is_valid(struct ocf_user_part *user_part)
+{
+ return !!user_part->config->flags.valid;
+}
+
+static inline void ocf_user_part_set_prio(struct ocf_cache *cache,
+ struct ocf_user_part *user_part, int16_t prio)
+{
+ if (user_part->config->priority != prio)
+ user_part->config->priority = prio;
+}
+
+static inline int16_t ocf_user_part_get_prio(struct ocf_cache *cache,
+ ocf_part_id_t part_id)
+{
+ if (part_id < OCF_USER_IO_CLASS_MAX)
+ return cache->user_parts[part_id].config->priority;
+
+ return OCF_IO_CLASS_PRIO_LOWEST;
+}
+
+void ocf_user_part_set_valid(struct ocf_cache *cache, ocf_part_id_t id,
+ bool valid);
+
+static inline bool ocf_user_part_is_added(struct ocf_user_part *user_part)
+{
+ return !!user_part->config->flags.added;
+}
+
+static inline ocf_part_id_t ocf_user_part_class2id(ocf_cache_t cache, uint64_t class)
+{
+ if (class < OCF_USER_IO_CLASS_MAX)
+ if (cache->user_parts[class].config->flags.valid)
+ return class;
+
+ return PARTITION_DEFAULT;
+}
+
+static inline uint32_t ocf_part_get_occupancy(struct ocf_part *part)
+{
+ return env_atomic_read(&part->runtime->curr_size);
+}
+
+static inline uint32_t ocf_user_part_get_min_size(ocf_cache_t cache,
+ struct ocf_user_part *user_part)
+{
+ uint64_t ioclass_size;
+
+ ioclass_size = (uint64_t)user_part->config->min_size *
+ (uint64_t)cache->conf_meta->cachelines;
+
+ ioclass_size /= 100;
+
+ return (uint32_t)ioclass_size;
+}
+
+
+static inline uint32_t ocf_user_part_get_max_size(ocf_cache_t cache,
+ struct ocf_user_part *user_part)
+{
+ uint64_t ioclass_size, max_size, cache_size;
+
+ max_size = user_part->config->max_size;
+ cache_size = cache->conf_meta->cachelines;
+
+ ioclass_size = max_size * cache_size;
+ ioclass_size = OCF_DIV_ROUND_UP(ioclass_size, 100);
+
+ return (uint32_t)ioclass_size;
+}
+
+void ocf_user_part_move(struct ocf_request *req);
+
+#define for_each_user_part(cache, user_part, id) \
+ for_each_lst_entry(&cache->user_part_list, user_part, id, \
+ struct ocf_user_part, lst_valid)
+
+static inline void ocf_user_part_sort(struct ocf_cache *cache)
+{
+ ocf_lst_sort(&cache->user_part_list);
+}
+
+static inline bool ocf_user_part_is_enabled(struct ocf_user_part *user_part)
+{
+ return user_part->config->max_size != 0;
+}
+
+static inline uint32_t ocf_user_part_overflow_size(struct ocf_cache *cache,
+ struct ocf_user_part *user_part)
+{
+ uint32_t part_occupancy = ocf_part_get_occupancy(&user_part->part);
+ uint32_t part_occupancy_limit = ocf_user_part_get_max_size(cache,
+ user_part);
+
+ if (part_occupancy > part_occupancy_limit)
+ return part_occupancy - part_occupancy_limit;
+
+ return 0;
+}
+
+static inline bool ocf_user_part_has_space(struct ocf_request *req)
+{
+ struct ocf_user_part *user_part = &req->cache->user_parts[req->part_id];
+ uint64_t part_occupancy_limit =
+ ocf_user_part_get_max_size(req->cache, user_part);
+ uint64_t needed_cache_lines = ocf_engine_repart_count(req) +
+ ocf_engine_unmapped_count(req);
+ uint64_t part_occupancy = ocf_part_get_occupancy(&user_part->part);
+
+ return (part_occupancy + needed_cache_lines <= part_occupancy_limit);
+}
+
+static inline ocf_cache_mode_t ocf_user_part_get_cache_mode(ocf_cache_t cache,
+ ocf_part_id_t part_id)
+{
+ if (part_id < OCF_USER_IO_CLASS_MAX)
+ return cache->user_parts[part_id].config->cache_mode;
+ return ocf_cache_mode_none;
+}
+
+static inline bool ocf_user_part_is_prio_valid(int64_t prio)
+{
+ switch (prio) {
+ case OCF_IO_CLASS_PRIO_HIGHEST ... OCF_IO_CLASS_PRIO_LOWEST:
+ case OCF_IO_CLASS_PRIO_PINNED:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/**
+ * routine checks for validity of a partition name.
+ *
+ * Following condition is checked:
+ * - string too long
+ * - string containing invalid characters (outside of low ascii)
+ * Following condition is NOT cheched:
+ * - empty string. (empty string is NOT a valid partition name, but
+ * this function returns true on empty string nevertheless).
+ *
+ * @return returns true if partition name is a valid name
+ */
+static inline bool ocf_user_part_is_name_valid(const char *name)
+{
+ uint32_t length = 0;
+
+ while (*name) {
+ if (*name < ' ' || *name > '~')
+ return false;
+
+ if (',' == *name || '"' == *name)
+ return false;
+
+ name++;
+ length++;
+
+ if (length >= OCF_IO_CLASS_NAME_MAX)
+ return false;
+ }
+
+ return true;
+}
+
+#endif /* __UTILS_PARTITION_H__ */
diff --git a/tests/functional/pyocf/types/cache.py b/tests/functional/pyocf/types/cache.py
index a1bef30..f4c88ca 100644
--- a/tests/functional/pyocf/types/cache.py
+++ b/tests/functional/pyocf/types/cache.py
@@ -48,7 +48,6 @@ class CacheConfig(Structure):
_fields_ = [
("_name", c_char * MAX_CACHE_NAME_SIZE),
("_cache_mode", c_uint32),
- ("_eviction_policy", c_uint32),
("_promotion_policy", c_uint32),
("_cache_line_size", c_uint64),
("_metadata_layout", c_uint32),
@@ -115,11 +114,6 @@ class CacheMode(IntEnum):
return self.value not in [CacheMode.PT, CacheMode.WO]
-class EvictionPolicy(IntEnum):
- LRU = 0
- DEFAULT = LRU
-
-
class PromotionPolicy(IntEnum):
ALWAYS = 0
NHIT = 1
@@ -167,7 +161,6 @@ class Cache:
owner,
name: str = "cache",
cache_mode: CacheMode = CacheMode.DEFAULT,
- eviction_policy: EvictionPolicy = EvictionPolicy.DEFAULT,
promotion_policy: PromotionPolicy = PromotionPolicy.DEFAULT,
cache_line_size: CacheLineSize = CacheLineSize.DEFAULT,
metadata_layout: MetadataLayout = MetadataLayout.DEFAULT,
@@ -186,7 +179,6 @@ class Cache:
self.cfg = CacheConfig(
_name=name.encode("ascii"),
_cache_mode=cache_mode,
- _eviction_policy=eviction_policy,
_promotion_policy=promotion_policy,
_cache_line_size=cache_line_size,
_metadata_layout=metadata_layout,
@@ -351,7 +343,6 @@ class Cache:
"_curr_size": (ioclass_info._curr_size),
"_min_size": int(ioclass_info._min_size),
"_max_size": int(ioclass_info._max_size),
- "_eviction_policy_type": int(ioclass_info._eviction_policy_type),
"_cleaning_policy_type": int(ioclass_info._cleaning_policy_type),
}
@@ -625,7 +616,6 @@ class Cache:
"status": cache_info.fallback_pt.status,
},
"state": cache_info.state,
- "eviction_policy": EvictionPolicy(cache_info.eviction_policy),
"cleaning_policy": CleaningPolicy(cache_info.cleaning_policy),
"promotion_policy": PromotionPolicy(cache_info.promotion_policy),
"cache_line_size": line_size,
diff --git a/tests/functional/pyocf/types/ioclass.py b/tests/functional/pyocf/types/ioclass.py
index 908f281..2d03c08 100644
--- a/tests/functional/pyocf/types/ioclass.py
+++ b/tests/functional/pyocf/types/ioclass.py
@@ -15,7 +15,6 @@ class IoClassInfo(Structure):
("_curr_size", c_uint32),
("_min_size", c_uint32),
("_max_size", c_uint32),
- ("_eviction_policy_type", c_uint8),
("_cleaning_policy_type", c_int),
]
diff --git a/tests/functional/pyocf/types/stats/cache.py b/tests/functional/pyocf/types/stats/cache.py
index 521416d..a624cc6 100644
--- a/tests/functional/pyocf/types/stats/cache.py
+++ b/tests/functional/pyocf/types/stats/cache.py
@@ -28,7 +28,6 @@ class CacheInfo(Structure):
("dirty_for", c_uint64),
("cache_mode", c_uint32),
("fallback_pt", _FallbackPt),
- ("eviction_policy", c_uint32),
("cleaning_policy", c_uint32),
("promotion_policy", c_uint32),
("cache_line_size", c_uint64),
diff --git a/tests/functional/tests/management/test_attach_cache.py b/tests/functional/tests/management/test_attach_cache.py
index 56557a3..1cd9d17 100644
--- a/tests/functional/tests/management/test_attach_cache.py
+++ b/tests/functional/tests/management/test_attach_cache.py
@@ -15,7 +15,6 @@ from pyocf.types.cache import (
Cache,
CacheMode,
MetadataLayout,
- EvictionPolicy,
CleaningPolicy,
)
from pyocf.types.core import Core
diff --git a/tests/functional/tests/management/test_start_stop.py b/tests/functional/tests/management/test_start_stop.py
index 42149a8..7edef73 100644
--- a/tests/functional/tests/management/test_start_stop.py
+++ b/tests/functional/tests/management/test_start_stop.py
@@ -11,7 +11,7 @@ from itertools import count
import pytest
from pyocf.ocf import OcfLib
-from pyocf.types.cache import Cache, CacheMode, MetadataLayout, EvictionPolicy, CleaningPolicy
+from pyocf.types.cache import Cache, CacheMode, MetadataLayout, CleaningPolicy
from pyocf.types.core import Core
from pyocf.types.data import Data
from pyocf.types.io import IoDir
@@ -38,7 +38,6 @@ def test_start_check_default(pyocf_ctx):
assert stats["conf"]["cleaning_policy"] == CleaningPolicy.DEFAULT
assert stats["conf"]["cache_mode"] == CacheMode.DEFAULT
assert stats["conf"]["cache_line_size"] == CacheLineSize.DEFAULT
- assert stats["conf"]["eviction_policy"] == EvictionPolicy.DEFAULT
core_stats = core.get_stats()
assert core_stats["seq_cutoff_policy"] == SeqCutOffPolicy.DEFAULT
@@ -156,7 +155,6 @@ def test_start_params(pyocf_ctx, mode: CacheMode, cls: CacheLineSize, layout: Me
stats = cache.get_stats()
assert stats["conf"]["cache_mode"] == mode, "Cache mode"
assert stats["conf"]["cache_line_size"] == cls, "Cache line size"
- assert stats["conf"]["eviction_policy"] == EvictionPolicy.DEFAULT, "Eviction policy"
assert cache.get_name() == name, "Cache name"
# TODO: metadata_layout, metadata_volatile, max_queue_size,
# queue_unblock_size, pt_unaligned_io, use_submit_fast
diff --git a/tests/functional/tests/security/conftest.py b/tests/functional/tests/security/conftest.py
index 44eb9cf..a38ec40 100644
--- a/tests/functional/tests/security/conftest.py
+++ b/tests/functional/tests/security/conftest.py
@@ -13,7 +13,7 @@ from ctypes import (
)
from tests.utils.random import RandomStringGenerator, RandomGenerator, DefaultRanges, Range
-from pyocf.types.cache import CacheMode, EvictionPolicy, MetadataLayout, PromotionPolicy
+from pyocf.types.cache import CacheMode, MetadataLayout, PromotionPolicy
from pyocf.types.shared import CacheLineSize
import pytest
@@ -77,13 +77,6 @@ def not_cache_line_size_randomize(request):
return request.param
-@pytest.fixture(
- params=RandomGenerator(DefaultRanges.UINT32).exclude_range(enum_range(EvictionPolicy))
-)
-def not_eviction_policy_randomize(request):
- return request.param
-
-
@pytest.fixture(
params=RandomGenerator(DefaultRanges.UINT32).exclude_range(enum_range(PromotionPolicy))
)
diff --git a/tests/functional/tests/security/test_management_start_fuzzy.py b/tests/functional/tests/security/test_management_start_fuzzy.py
index c152b78..49b78dc 100644
--- a/tests/functional/tests/security/test_management_start_fuzzy.py
+++ b/tests/functional/tests/security/test_management_start_fuzzy.py
@@ -7,7 +7,7 @@ import logging
import pytest
-from pyocf.types.cache import Cache, CacheMode, EvictionPolicy, MetadataLayout, PromotionPolicy
+from pyocf.types.cache import Cache, CacheMode, MetadataLayout, PromotionPolicy
from pyocf.types.shared import OcfError, CacheLineSize
from pyocf.types.volume import Volume
from pyocf.utils import Size
@@ -73,25 +73,6 @@ def test_fuzzy_start_name(pyocf_ctx, string_randomize, cm, cls):
cache.stop()
-@pytest.mark.security
-@pytest.mark.parametrize("cm", CacheMode)
-@pytest.mark.parametrize("cls", CacheLineSize)
-def test_fuzzy_start_eviction_policy(pyocf_ctx, not_eviction_policy_randomize, cm, cls):
- """
- Test whether it is impossible to start cache with invalid eviction policy value.
- :param pyocf_ctx: basic pyocf context fixture
- :param c_uint32_randomize: eviction policy enum value to start cache with
- :param cm: cache mode value to start cache with
- :param cls: cache line size value to start cache with
- """
- with pytest.raises(OcfError, match="OCF_ERR_INVAL"):
- try_start_cache(
- eviction_policy=not_eviction_policy_randomize,
- cache_mode=cm,
- cache_line_size=cls
- )
-
-
@pytest.mark.security
@pytest.mark.parametrize("cm", CacheMode)
@pytest.mark.parametrize("cls", CacheLineSize)
diff --git a/tests/unit/framework/tests_config.py b/tests/unit/framework/tests_config.py
index 146daf2..2c3a794 100644
--- a/tests/unit/framework/tests_config.py
+++ b/tests/unit/framework/tests_config.py
@@ -16,7 +16,7 @@ MAIN_DIRECTORY_OF_UNIT_TESTS = "../tests/"
# Paths to all directories, in which tests are stored. All paths should be relative to
# MAIN_DIRECTORY_OF_UNIT_TESTS
DIRECTORIES_WITH_TESTS_LIST = ["cleaning/", "metadata/", "mngt/", "concurrency/", "engine/",
- "eviction/", "utils/", "promotion/", "ocf_freelist.c/"]
+ "ocf_space.c/", "ocf_lru.c/", "utils/", "promotion/"]
# Paths to all directories containing files with sources. All paths should be relative to
# MAIN_DIRECTORY_OF_TESTED_PROJECT
diff --git a/tests/unit/tests/cleaning/alru.c/cleaning_policy_alru_initialize_part_test.c b/tests/unit/tests/cleaning/alru.c/cleaning_policy_alru_initialize_part_test.c
index f233827..323091c 100644
--- a/tests/unit/tests/cleaning/alru.c/cleaning_policy_alru_initialize_part_test.c
+++ b/tests/unit/tests/cleaning/alru.c/cleaning_policy_alru_initialize_part_test.c
@@ -30,7 +30,7 @@
#include "alru.h"
#include "../metadata/metadata.h"
#include "../utils/utils_cleaner.h"
-#include "../utils/utils_part.h"
+#include "../utils/utils_user_part.h"
#include "../utils/utils_realloc.h"
#include "../concurrency/ocf_cache_line_concurrency.h"
#include "../ocf_def_priv.h"
@@ -49,7 +49,9 @@ static void cleaning_policy_alru_initialize_test01(void **state)
print_test_description("Check if all variables are set correctly");
cache = test_malloc(sizeof(*cache));
- cache->user_parts[part_id].runtime = test_malloc(sizeof(struct ocf_user_part_runtime));
+ cache->user_parts[part_id].part.runtime = test_malloc(sizeof(struct ocf_part_runtime));
+ cache->user_parts[part_id].clean_pol = test_malloc(sizeof(*cache->user_parts[part_id].clean_pol));
+ cache->user_parts[part_id].part.id = part_id;
cache->device = test_malloc(sizeof(struct ocf_cache_device));
cache->device->runtime_meta = test_malloc(sizeof(struct ocf_superblock_runtime));
@@ -59,15 +61,16 @@ static void cleaning_policy_alru_initialize_test01(void **state)
assert_int_equal(result, 0);
- assert_int_equal(env_atomic_read(&cache->user_parts[part_id].runtime->cleaning.policy.alru.size), 0);
- assert_int_equal(cache->user_parts[part_id].runtime->cleaning.policy.alru.lru_head, collision_table_entries);
- assert_int_equal(cache->user_parts[part_id].runtime->cleaning.policy.alru.lru_tail, collision_table_entries);
+ assert_int_equal(env_atomic_read(&cache->user_parts[part_id].clean_pol->policy.alru.size), 0);
+ assert_int_equal(cache->user_parts[part_id].clean_pol->policy.alru.lru_head, collision_table_entries);
+ assert_int_equal(cache->user_parts[part_id].clean_pol->policy.alru.lru_tail, collision_table_entries);
assert_int_equal(cache->device->runtime_meta->cleaning_thread_access, 0);
test_free(cache->device->runtime_meta);
test_free(cache->device);
- test_free(cache->user_parts[part_id].runtime);
+ test_free(cache->user_parts[part_id].clean_pol);
+ test_free(cache->user_parts[part_id].part.runtime);
test_free(cache);
}
@@ -82,27 +85,29 @@ static void cleaning_policy_alru_initialize_test02(void **state)
print_test_description("Check if only appropirate variables are changed");
cache = test_malloc(sizeof(*cache));
- cache->user_parts[part_id].runtime = test_malloc(sizeof(struct ocf_user_part_runtime));
+ cache->user_parts[part_id].part.runtime = test_malloc(sizeof(struct ocf_part_runtime));
+ cache->user_parts[part_id].clean_pol = test_malloc(sizeof(*cache->user_parts[part_id].clean_pol));
cache->device = test_malloc(sizeof(struct ocf_cache_device));
cache->device->runtime_meta = test_malloc(sizeof(struct ocf_superblock_runtime));
- env_atomic_set(&cache->user_parts[part_id].runtime->cleaning.policy.alru.size, 1);
- cache->user_parts[part_id].runtime->cleaning.policy.alru.lru_head = -collision_table_entries;
- cache->user_parts[part_id].runtime->cleaning.policy.alru.lru_tail = -collision_table_entries;
+ env_atomic_set(&cache->user_parts[part_id].clean_pol->policy.alru.size, 1);
+ cache->user_parts[part_id].clean_pol->policy.alru.lru_head = -collision_table_entries;
+ cache->user_parts[part_id].clean_pol->policy.alru.lru_tail = -collision_table_entries;
- result = cleaning_policy_alru_initialize_part(cache, cache->user_parts[part_id], 0, 0);
+ result = cleaning_policy_alru_initialize_part(cache, &cache->user_parts[part_id], 0, 0);
assert_int_equal(result, 0);
- assert_int_equal(env_atomic_read(&cache->user_parts[part_id].runtime->cleaning.policy.alru.size), 1);
- assert_int_equal(cache->user_parts[part_id].runtime->cleaning.policy.alru.lru_head, -collision_table_entries);
- assert_int_equal(cache->user_parts[part_id].runtime->cleaning.policy.alru.lru_tail, -collision_table_entries);
+ assert_int_equal(env_atomic_read(&cache->user_parts[part_id].clean_pol->policy.alru.size), 1);
+ assert_int_equal(cache->user_parts[part_id].clean_pol->policy.alru.lru_head, -collision_table_entries);
+ assert_int_equal(cache->user_parts[part_id].clean_pol->policy.alru.lru_tail, -collision_table_entries);
assert_int_equal(cache->device->runtime_meta->cleaning_thread_access, 0);
test_free(cache->device->runtime_meta);
test_free(cache->device);
- test_free(cache->user_parts[part_id].runtime);
+ test_free(cache->user_parts[part_id].clean_pol);
+ test_free(cache->user_parts[part_id].part.runtime);
test_free(cache);
}
diff --git a/tests/unit/tests/engine/engine_common.c/prepare_clines_miss.c b/tests/unit/tests/engine/engine_common.c/prepare_clines_miss.c
index ac38591..e74b3c6 100644
--- a/tests/unit/tests/engine/engine_common.c/prepare_clines_miss.c
+++ b/tests/unit/tests/engine/engine_common.c/prepare_clines_miss.c
@@ -3,7 +3,11 @@
* ocf_prepare_clines_miss
*
* ocf_prepare_clines_evict
- * ocf_engine_evict
+ * ocf_engine_remap
+ * ocf_req_set_mapping_error
+ * ocf_req_test_mapping_error
+ * ocf_req_set_part_evict
+ * ocf_req_part_evict
*
*/
@@ -22,15 +26,14 @@
#include "../ocf_priv.h"
#include "../ocf_cache_priv.h"
#include "../ocf_queue_priv.h"
-#include "../ocf_freelist.h"
#include "engine_common.h"
#include "engine_debug.h"
#include "../utils/utils_cache_line.h"
#include "../ocf_request.h"
#include "../utils/utils_cleaner.h"
-#include "../utils/utils_part.h"
+#include "../utils/utils_user_part.h"
#include "../metadata/metadata.h"
-#include "../eviction/eviction.h"
+#include "../ocf_space.h"
#include "../promotion/promotion.h"
#include "../concurrency/ocf_concurrency.h"
@@ -49,7 +52,7 @@ void __wrap_ocf_req_hash_unlock_wr(struct ocf_request *req)
{
}
-uint32_t __wrap_ocf_part_has_space(struct ocf_request *req)
+uint32_t __wrap_ocf_user_part_has_space(struct ocf_request *req)
{
return mock();
}
@@ -71,45 +74,27 @@ void __wrap_ocf_metadata_end_exclusive_access(
{
}
-bool __wrap_ocf_part_is_enabled(struct ocf_user_part *target_part)
-{
- return mock();
-}
-
-void __wrap_ocf_engine_map(struct ocf_request *req)
-{
- function_called();
-}
-
-bool __wrap_ocf_req_test_mapping_error(struct ocf_request *req)
-{
- return mock();
-}
-
-void __wrap_ocf_req_set_mapping_error(struct ocf_request *req)
-{
- function_called();
-}
-
-int __wrap_space_managment_evict_do(struct ocf_request *req)
+int __wrap_ocf_space_managment_remap_do(struct ocf_request *req)
{
function_called();
return mock();
}
-uint32_t __wrap_ocf_engine_unmapped_count(struct ocf_request *req)
-{
- return 100;
-}
-
static void ocf_prepare_clines_miss_test01(void **state)
{
struct ocf_cache cache;
struct ocf_request req = {.cache = &cache };
- print_test_description("Target part is disabled and empty\n");
- will_return(__wrap_ocf_part_is_enabled, false);
- expect_function_call(__wrap_ocf_req_set_mapping_error);
- assert_int_equal(ocf_prepare_clines_miss(&req, NULL), -OCF_ERR_NO_LOCK);
+
+ print_test_description("Target part doesn't have enough space.\n");
+ print_test_description("\tEviction success\n");
+
+ will_return_always(__wrap_ocf_user_part_has_space, false);
+ expect_function_call(__wrap_ocf_space_managment_remap_do);
+ will_return_always(__wrap_ocf_space_managment_remap_do, LOOKUP_REMAPPED);
+
+ ocf_prepare_clines_miss(&req);
+ assert(!ocf_req_test_mapping_error(&req));
+ assert(ocf_req_part_evict(&req));
}
static void ocf_prepare_clines_miss_test02(void **state)
@@ -117,13 +102,17 @@ static void ocf_prepare_clines_miss_test02(void **state)
struct ocf_cache cache;
struct ocf_request req = {.cache = &cache };
- print_test_description("Target part is disabled but has cachelines assigned.\n");
- print_test_description("\tMark mapping error\n");
+ print_test_description("Target part doesn't have enough space.\n");
+ print_test_description("\tEviction failed\n");
- will_return(__wrap_ocf_part_is_enabled, false);
- expect_function_call(__wrap_ocf_req_set_mapping_error);
+ will_return_always(__wrap_ocf_user_part_has_space, false);
- assert_int_equal(ocf_prepare_clines_miss(&req, NULL), -OCF_ERR_NO_LOCK);
+ expect_function_call(__wrap_ocf_space_managment_remap_do);
+ will_return(__wrap_ocf_space_managment_remap_do, LOOKUP_MISS);
+
+ ocf_prepare_clines_miss(&req);
+ assert(ocf_req_test_mapping_error(&req));
+ assert(ocf_req_part_evict(&req));
}
static void ocf_prepare_clines_miss_test03(void **state)
@@ -131,20 +120,16 @@ static void ocf_prepare_clines_miss_test03(void **state)
struct ocf_cache cache;
struct ocf_request req = {.cache = &cache };
- print_test_description("Target part is enabled but doesn't have enough space.\n");
- print_test_description("\tEviction is ok and cachelines lock is acquired.\n");
+ print_test_description("Target part has enough space.\n");
+ print_test_description("\tEviction success\n");
- will_return(__wrap_ocf_part_is_enabled, true);
- will_return_always(__wrap_ocf_part_has_space, false);
- expect_function_call(__wrap_space_managment_evict_do);
- will_return_always(__wrap_space_managment_evict_do, LOOKUP_INSERTED);
+ will_return_always(__wrap_ocf_user_part_has_space, true);
+ expect_function_call(__wrap_ocf_space_managment_remap_do);
+ will_return_always(__wrap_ocf_space_managment_remap_do, LOOKUP_REMAPPED);
- will_return_always(__wrap_ocf_req_test_mapping_error, false);
-
- will_return(__wrap_lock_clines, 0);
- expect_function_call(__wrap_lock_clines);
-
- assert_int_equal(ocf_prepare_clines_miss(&req, NULL), 0);
+ ocf_prepare_clines_miss(&req);
+ assert(!ocf_req_test_mapping_error(&req));
+ assert(!ocf_req_part_evict(&req));
}
static void ocf_prepare_clines_miss_test04(void **state)
@@ -152,85 +137,17 @@ static void ocf_prepare_clines_miss_test04(void **state)
struct ocf_cache cache;
struct ocf_request req = {.cache = &cache };
- print_test_description("Target part is enabled but doesn't have enough space.\n");
+ print_test_description("Target part has enough space.\n");
print_test_description("\tEviction failed\n");
- will_return(__wrap_ocf_part_is_enabled, true);
- will_return_always(__wrap_ocf_part_has_space, false);
+ will_return_always(__wrap_ocf_user_part_has_space, true);
- expect_function_call(__wrap_space_managment_evict_do);
- will_return(__wrap_space_managment_evict_do, LOOKUP_MISS);
- expect_function_call(__wrap_ocf_req_set_mapping_error);
- will_return_always(__wrap_ocf_req_test_mapping_error, true);
+ expect_function_call(__wrap_ocf_space_managment_remap_do);
+ will_return(__wrap_ocf_space_managment_remap_do, LOOKUP_MISS);
- assert_int_equal(ocf_prepare_clines_miss(&req, NULL), -OCF_ERR_NO_LOCK);
-}
-
-static void ocf_prepare_clines_miss_test06(void **state)
-{
- struct ocf_cache cache;
- struct ocf_request req = {.cache = &cache };
-
- print_test_description("Target part is enabled but doesn't have enough space.\n");
- print_test_description("Eviction and mapping were ok, but failed to lock cachelines.\n");
-
- will_return_always(__wrap_ocf_part_has_space, false);
-
- expect_function_call(__wrap_space_managment_evict_do);
- will_return(__wrap_space_managment_evict_do, LOOKUP_HIT);
-
- will_return(__wrap_ocf_part_is_enabled, true);
- will_return_always(__wrap_ocf_req_test_mapping_error, false);
-
- expect_function_call(__wrap_lock_clines);
- will_return(__wrap_lock_clines, -OCF_ERR_NO_LOCK);
-
- expect_function_call(__wrap_ocf_req_set_mapping_error);
-
- assert_int_equal(ocf_prepare_clines_miss(&req, NULL), -OCF_ERR_NO_LOCK);
-}
-
-static void ocf_prepare_clines_miss_test07(void **state)
-{
- struct ocf_cache cache;
- struct ocf_request req = {.cache = &cache };
-
- print_test_description("Target part is enabled but doesn't have enough space.\n");
- print_test_description("Eviction and mapping were ok, lock not acquired.\n");
-
- will_return_always(__wrap_ocf_part_has_space, false);
-
- expect_function_call(__wrap_space_managment_evict_do);
- will_return(__wrap_space_managment_evict_do, LOOKUP_HIT);
-
- will_return(__wrap_ocf_part_is_enabled, true);
-
- will_return_always(__wrap_ocf_req_test_mapping_error, false);
-
- expect_function_call(__wrap_lock_clines);
- will_return(__wrap_lock_clines, OCF_LOCK_NOT_ACQUIRED);
-
- assert_int_equal(ocf_prepare_clines_miss(&req, NULL), OCF_LOCK_NOT_ACQUIRED);
-}
-
-static void ocf_prepare_clines_miss_test08(void **state)
-{
- struct ocf_cache cache;
- struct ocf_request req = {.cache = &cache };
-
- print_test_description("Target part is enabled has enough space.\n");
- print_test_description("\tMapping and cacheline lock are both ok\n");
-
- will_return(__wrap_ocf_part_is_enabled, true);
- will_return_always(__wrap_ocf_part_has_space, true);
-
- expect_function_call(__wrap_ocf_engine_map);
- will_return_always(__wrap_ocf_req_test_mapping_error, false);
-
- expect_function_call(__wrap_lock_clines);
- will_return(__wrap_lock_clines, OCF_LOCK_ACQUIRED);
-
- assert_int_equal(ocf_prepare_clines_miss(&req, NULL), OCF_LOCK_ACQUIRED);
+ ocf_prepare_clines_miss(&req);
+ assert(ocf_req_test_mapping_error(&req));
+ assert(!ocf_req_part_evict(&req));
}
int main(void)
@@ -240,9 +157,6 @@ int main(void)
cmocka_unit_test(ocf_prepare_clines_miss_test02),
cmocka_unit_test(ocf_prepare_clines_miss_test03),
cmocka_unit_test(ocf_prepare_clines_miss_test04),
- cmocka_unit_test(ocf_prepare_clines_miss_test06),
- cmocka_unit_test(ocf_prepare_clines_miss_test07),
- cmocka_unit_test(ocf_prepare_clines_miss_test08)
};
print_message("Unit test for ocf_prepare_clines_miss\n");
diff --git a/tests/unit/tests/mngt/ocf_mngt_cache.c/_cache_mngt_set_cache_mode_test.c b/tests/unit/tests/mngt/ocf_mngt_cache.c/_cache_mngt_set_cache_mode_test.c
index b7a00d2..2dd93c9 100644
--- a/tests/unit/tests/mngt/ocf_mngt_cache.c/_cache_mngt_set_cache_mode_test.c
+++ b/tests/unit/tests/mngt/ocf_mngt_cache.c/_cache_mngt_set_cache_mode_test.c
@@ -30,13 +30,13 @@ ocf_mngt_cache_mode_has_lazy_write
#include "../ocf_queue_priv.h"
#include "../metadata/metadata.h"
#include "../engine/cache_engine.h"
-#include "../utils/utils_part.h"
+#include "../utils/utils_user_part.h"
#include "../utils/utils_cache_line.h"
#include "../utils/utils_io.h"
#include "../utils/utils_cache_line.h"
#include "../utils/utils_pipeline.h"
#include "../concurrency/ocf_concurrency.h"
-#include "../eviction/ops.h"
+#include "../ocf_lru.h"
#include "../ocf_ctx_priv.h"
#include "../cleaning/cleaning.h"
diff --git a/tests/unit/tests/mngt/ocf_mngt_cache.c/ocf_mngt_cache_set_fallback_pt_error_threshold.c b/tests/unit/tests/mngt/ocf_mngt_cache.c/ocf_mngt_cache_set_fallback_pt_error_threshold.c
index e14b6aa..84898b7 100644
--- a/tests/unit/tests/mngt/ocf_mngt_cache.c/ocf_mngt_cache_set_fallback_pt_error_threshold.c
+++ b/tests/unit/tests/mngt/ocf_mngt_cache.c/ocf_mngt_cache_set_fallback_pt_error_threshold.c
@@ -24,13 +24,13 @@
#include "../ocf_queue_priv.h"
#include "../metadata/metadata.h"
#include "../engine/cache_engine.h"
-#include "../utils/utils_part.h"
+#include "../utils/utils_user_part.h"
#include "../utils/utils_cache_line.h"
#include "../utils/utils_io.h"
#include "../utils/utils_cache_line.h"
#include "../utils/utils_pipeline.h"
#include "../concurrency/ocf_concurrency.h"
-#include "../eviction/ops.h"
+#include "../ocf_lru.h"
#include "../ocf_ctx_priv.h"
#include "../cleaning/cleaning.h"
diff --git a/tests/unit/tests/mngt/ocf_mngt_io_class.c/ocf_mngt_io_class.c b/tests/unit/tests/mngt/ocf_mngt_io_class.c/ocf_mngt_io_class.c
index 3445109..8777284 100644
--- a/tests/unit/tests/mngt/ocf_mngt_io_class.c/ocf_mngt_io_class.c
+++ b/tests/unit/tests/mngt/ocf_mngt_io_class.c/ocf_mngt_io_class.c
@@ -31,14 +31,14 @@
#include "../ocf_priv.h"
#include "../metadata/metadata.h"
#include "../engine/cache_engine.h"
-#include "../utils/utils_part.h"
-#include "../eviction/ops.h"
+#include "../utils/utils_user_part.h"
+#include "../ocf_lru.h"
#include "ocf_env.h"
#include "mngt/ocf_mngt_io_class.c/ocf_mngt_io_class_generated_wraps.c"
/* Functions mocked for testing purposes */
-bool __wrap_ocf_part_is_added(struct ocf_user_part *part)
+bool __wrap_ocf_user_part_is_added(struct ocf_user_part *user_part)
{
function_called();
return mock();
@@ -51,20 +51,20 @@ int __wrap__ocf_mngt_set_partition_size(struct ocf_cache *cache,
return mock();
}
-void __wrap_ocf_part_set_prio(struct ocf_cache *cache,
- struct ocf_user_part *part, int16_t prio)
+void __wrap_ocf_user_part_set_prio(struct ocf_cache *cache,
+ struct ocf_user_part *user_part, int16_t prio)
{
function_called();
}
-bool __wrap_ocf_part_is_valid(struct ocf_user_part *part)
+bool __wrap_ocf_user_part_is_valid(struct ocf_user_part *user_part)
{
function_called();
return mock();
}
-void __wrap_ocf_part_set_valid(struct ocf_cache *cache, ocf_part_id_t id,
+void __wrap_ocf_user_part_set_valid(struct ocf_cache *cache, ocf_part_id_t id,
bool valid)
{
function_called();
@@ -79,7 +79,7 @@ int __wrap__ocf_mngt_io_class_validate_cfg(ocf_cache_t cache,
return mock();
}
-void __wrap_ocf_part_sort(struct ocf_cache *cache)
+void __wrap_ocf_user_part_sort(struct ocf_cache *cache)
{
function_called();
}
@@ -93,7 +93,7 @@ static inline void setup_valid_config(struct ocf_mngt_io_class_config *cfg,
bool remove)
{
int i;
- for (i = 0; i < OCF_IO_CLASS_MAX; i++) {
+ for (i = 0; i < OCF_USER_IO_CLASS_MAX; i++) {
cfg[i].class_id = i;
cfg[i].name = remove ? NULL : i == 0 ? "unclassified" :"test_io_class_name" ;
cfg[i].prio = i;
@@ -112,7 +112,7 @@ static void ocf_mngt_io_classes_configure_test03(void **state)
cache = test_malloc(sizeof(*cache));
- for (i = 0; i < OCF_IO_CLASS_MAX; i++) {
+ for (i = 0; i < OCF_USER_IO_CLASS_MAX; i++) {
cache->user_parts[i].config =
test_malloc(sizeof(struct ocf_user_part_config));
}
@@ -120,30 +120,30 @@ static void ocf_mngt_io_classes_configure_test03(void **state)
setup_valid_config(cfg.config, true);
- for (i = 0; i < OCF_IO_CLASS_MAX; i++) {
+ for (i = 0; i < OCF_USER_IO_CLASS_MAX; i++) {
expect_function_call(__wrap__ocf_mngt_io_class_validate_cfg);
will_return(__wrap__ocf_mngt_io_class_validate_cfg, 0);
}
/* Removing default io_class is not allowed */
- for (i = 1; i < OCF_IO_CLASS_MAX; i++) {
- expect_function_call(__wrap_ocf_part_is_valid);
- will_return(__wrap_ocf_part_is_valid, 1);
+ for (i = 1; i < OCF_USER_IO_CLASS_MAX; i++) {
+ expect_function_call(__wrap_ocf_user_part_is_valid);
+ will_return(__wrap_ocf_user_part_is_valid, 1);
- expect_function_call(__wrap_ocf_part_set_valid);
+ expect_function_call(__wrap_ocf_user_part_set_valid);
/* Test assumes default partition has id equal 0 */
- expect_in_range(__wrap_ocf_part_set_valid, id, OCF_IO_CLASS_ID_MIN + 1,
+ expect_in_range(__wrap_ocf_user_part_set_valid, id, OCF_IO_CLASS_ID_MIN + 1,
OCF_IO_CLASS_ID_MAX);
- expect_value(__wrap_ocf_part_set_valid, valid, false);
+ expect_value(__wrap_ocf_user_part_set_valid, valid, false);
}
- expect_function_call(__wrap_ocf_part_sort);
+ expect_function_call(__wrap_ocf_user_part_sort);
result = ocf_mngt_cache_io_classes_configure(cache, &cfg);
assert_int_equal(result, 0);
- for (i = 0; i < OCF_IO_CLASS_MAX; i++)
+ for (i = 0; i < OCF_USER_IO_CLASS_MAX; i++)
test_free(cache->user_parts[i].config);
test_free(cache);
@@ -157,7 +157,7 @@ static void ocf_mngt_io_classes_configure_test02(void **state)
cache = test_malloc(sizeof(*cache));
- for (i = 0; i < OCF_IO_CLASS_MAX; i++) {
+ for (i = 0; i < OCF_USER_IO_CLASS_MAX; i++) {
cache->user_parts[i].config =
test_malloc(sizeof(struct ocf_user_part_config));
}
@@ -169,46 +169,46 @@ static void ocf_mngt_io_classes_configure_test02(void **state)
print_test_description("Configure all possible io classes");
- for (i = 0; i < OCF_IO_CLASS_MAX; i++) {
+ for (i = 0; i < OCF_USER_IO_CLASS_MAX; i++) {
expect_function_call(__wrap__ocf_mngt_io_class_validate_cfg);
will_return(__wrap__ocf_mngt_io_class_validate_cfg, 0);
}
/* Configure default io_class */
- expect_function_call(__wrap_ocf_part_is_added);
- will_return(__wrap_ocf_part_is_added, 1);
+ expect_function_call(__wrap_ocf_user_part_is_added);
+ will_return(__wrap_ocf_user_part_is_added, 1);
expect_function_call(__wrap__ocf_mngt_set_partition_size);
will_return(__wrap__ocf_mngt_set_partition_size, 0);
- expect_function_call(__wrap_ocf_part_set_prio);
+ expect_function_call(__wrap_ocf_user_part_set_prio);
/* Configure custom io_classes */
- for (i = 1; i < OCF_IO_CLASS_MAX; i++) {
- expect_function_call(__wrap_ocf_part_is_added);
- will_return(__wrap_ocf_part_is_added, 1);
+ for (i = 1; i < OCF_USER_IO_CLASS_MAX; i++) {
+ expect_function_call(__wrap_ocf_user_part_is_added);
+ will_return(__wrap_ocf_user_part_is_added, 1);
expect_function_call(__wrap__ocf_mngt_set_partition_size);
will_return(__wrap__ocf_mngt_set_partition_size, 0);
- expect_function_call(__wrap_ocf_part_is_valid);
- will_return(__wrap_ocf_part_is_valid, 0);
+ expect_function_call(__wrap_ocf_user_part_is_valid);
+ will_return(__wrap_ocf_user_part_is_valid, 0);
- expect_function_call(__wrap_ocf_part_set_valid);
- expect_in_range(__wrap_ocf_part_set_valid, id, OCF_IO_CLASS_ID_MIN,
+ expect_function_call(__wrap_ocf_user_part_set_valid);
+ expect_in_range(__wrap_ocf_user_part_set_valid, id, OCF_IO_CLASS_ID_MIN,
OCF_IO_CLASS_ID_MAX);
- expect_value(__wrap_ocf_part_set_valid, valid, true);
+ expect_value(__wrap_ocf_user_part_set_valid, valid, true);
- expect_function_call(__wrap_ocf_part_set_prio);
+ expect_function_call(__wrap_ocf_user_part_set_prio);
}
- expect_function_call(__wrap_ocf_part_sort);
+ expect_function_call(__wrap_ocf_user_part_sort);
result = ocf_mngt_cache_io_classes_configure(cache, &cfg);
assert_int_equal(result, 0);
- for (i = 0; i < OCF_IO_CLASS_MAX; i++)
+ for (i = 0; i < OCF_USER_IO_CLASS_MAX; i++)
test_free(cache->user_parts[i].config);
test_free(cache);
@@ -217,7 +217,7 @@ static void ocf_mngt_io_classes_configure_test02(void **state)
static void ocf_mngt_io_classes_configure_test01(void **state)
{
struct ocf_cache *cache;
- struct ocf_mngt_io_classes_config cfg[OCF_IO_CLASS_MAX];
+ struct ocf_mngt_io_classes_config cfg[OCF_USER_IO_CLASS_MAX];
int error_code = -OCF_ERR_INVAL;
int result;
diff --git a/tests/unit/tests/ocf_freelist.c/ocf_freelist_get_put.c b/tests/unit/tests/ocf_freelist.c/ocf_freelist_get_put.c
deleted file mode 100644
index e74feeb..0000000
--- a/tests/unit/tests/ocf_freelist.c/ocf_freelist_get_put.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * src/ocf_freelist.c
- * ocf_freelist_get_cache_line
- *
- * ocf_freelist_init
- * ocf_freelist_deinit
- * ocf_freelist_populate
- * next_phys_invalid
- * ocf_freelist_lock
- * ocf_freelist_trylock
- * ocf_freelist_unlock
- * _ocf_freelist_remove_cache_line
- * ocf_freelist_get_cache_line_fast
- * ocf_freelist_get_cache_line_slow
- * ocf_freelist_add_cache_line
- * ocf_freelist_get_cache_line_ctx
- * get_next_victim_freelist
- * ocf_freelist_put_cache_line
- *
- */
-
-#undef static
-
-#undef inline
-
-
-#include
-#include
-#include
-#include
-#include "print_desc.h"
-
-#include "ocf/ocf.h"
-#include "metadata/metadata.h"
-
-#include "ocf_freelist.c/ocf_freelist_get_put_generated_wraps.c"
-
-ocf_cache_line_t __wrap_ocf_metadata_collision_table_entries(ocf_cache_t cache)
-{
- return mock();
-}
-
-unsigned __wrap_env_get_execution_context_count(void)
-{
- return mock();
-}
-
-unsigned __wrap_env_get_execution_context(void)
-{
- return mock();
-}
-
-void __wrap_env_put_execution_context(unsigned ctx)
-{
-}
-
-/* simulate no striping */
-ocf_cache_line_t __wrap_ocf_metadata_map_phy2lg(ocf_cache_t cache, ocf_cache_line_t phy)
-{
- return phy;
-}
-
-bool __wrap_metadata_test_valid_any(ocf_cache_t cache, ocf_cache_line_t cline)
-{
- return mock();
-}
-
-/* metadata partition info interface mock: */
-
-#define max_clines 100
-
-struct {
- ocf_cache_line_t prev;
- ocf_cache_line_t next;
-} partition_list[max_clines];
-
-
-void __wrap_ocf_metadata_set_partition_info(struct ocf_cache *cache,
- ocf_cache_line_t line, ocf_part_id_t part_id,
- ocf_cache_line_t next_line, ocf_cache_line_t prev_line)
-{
- assert_int_equal(part_id, PARTITION_INVALID);
- partition_list[line].prev = prev_line;
- partition_list[line].next = next_line;
-}
-
-void __wrap_ocf_metadata_get_partition_info(struct ocf_cache *cache,
- ocf_cache_line_t line, ocf_part_id_t *part_id,
- ocf_cache_line_t *next_line, ocf_cache_line_t *prev_line)
-{
- if (part_id)
- *part_id = PARTITION_INVALID;
- if (prev_line)
- *prev_line = partition_list[line].prev;
- if (next_line)
- *next_line = partition_list[line].next;
-}
-
-void __wrap_ocf_metadata_set_partition_prev(struct ocf_cache *cache,
- ocf_cache_line_t line, ocf_cache_line_t prev_line)
-{
- partition_list[line].prev = prev_line;
-}
-
-void __wrap_ocf_metadata_set_partition_next(struct ocf_cache *cache,
- ocf_cache_line_t line, ocf_cache_line_t next_line)
-{
- partition_list[line].next = next_line;
-}
-
-static void ocf_freelist_get_cache_line_get_fast(void **state)
-{
- unsigned num_cls = 8;
- unsigned num_ctxts = 3;
- ocf_freelist_t freelist;
- unsigned ctx_iter, cl_iter;
- ocf_cache_line_t line;
-
- print_test_description("Verify get free cache line get fast path");
-
- will_return_maybe(__wrap_ocf_metadata_collision_table_entries, num_cls);
- will_return_maybe(__wrap_env_get_execution_context_count, num_ctxts);
- will_return_maybe(__wrap_metadata_test_valid_any, false);
-
- ocf_freelist_init(&freelist, NULL);
-
- ocf_freelist_populate(freelist, num_cls);
-
- /* now there are following cachelines on per-context lists:
- * ctx 0: 0, 1, 2
- * ctx 1: 3, 4, 5
- * ctx 2: 6, 7
- */
-
- /* get cline from context 1 */
- will_return(__wrap_env_get_execution_context, 1);
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 3);
-
- /* ctx 0: 0, 1, 2
- * ctx 1: _, 4, 5
- * ctx 2: 6, 7 */
-
- /* get cline from context 2 */
- will_return(__wrap_env_get_execution_context, 2);
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 6);
-
- /* ctx 0: 0, 1, 2
- * ctx 1: _, 4, 5
- * ctx 2: _, 7 */
-
- /* get cline from context 1 */
- will_return(__wrap_env_get_execution_context, 1);
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 4);
-
- /* ctx 0: 0, 1, 2
- * ctx 1: _, _, 5
- * ctx 2: _, 7 */
-
- /* get cline from context 0 */
- will_return(__wrap_env_get_execution_context, 0);
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 0);
-
- /* ctx 0: _, 1, 2
- * ctx 1: _, _, 5
- * ctx 2: _, 7 */
-
- /* get cline from context 0 */
- will_return(__wrap_env_get_execution_context, 0);
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 1);
-
- /* ctx 0: _, _, 2
- * ctx 1: _, _, 5
- * ctx 2: _, 7 */
-
- /* get cline from context 0 */
- will_return(__wrap_env_get_execution_context, 0);
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 2);
-
- /* ctx 0: _, _, _,
- * ctx 1: _, _, 5
- * ctx 2: _, 7 */
-
- /* get cline from context 2 */
- will_return(__wrap_env_get_execution_context, 2);
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 7);
-
- /* ctx 0: _, _, _,
- * ctx 1: _, _, _5
- * ctx 2: _, _ */
-
- /* get cline from context 1 */
- will_return(__wrap_env_get_execution_context, 1);
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 5);
-
- /* ctx 0: _, _, _,
- * ctx 1: _, _, _
- * ctx 2: _, _ */
-
- ocf_freelist_deinit(freelist);
-}
-
-static void ocf_freelist_get_cache_line_get_slow(void **state)
-{
- unsigned num_cls = 8;
- unsigned num_ctxts = 3;
- ocf_freelist_t freelist;
- unsigned ctx_iter, cl_iter;
- ocf_cache_line_t line;
-
- print_test_description("Verify get free cache line get slow path");
-
- will_return_maybe(__wrap_ocf_metadata_collision_table_entries, num_cls);
- will_return_maybe(__wrap_env_get_execution_context_count, num_ctxts);
- will_return_maybe(__wrap_metadata_test_valid_any, false);
-
- /* always return exec ctx 0 */
- will_return_maybe(__wrap_env_get_execution_context, 0);
-
- ocf_freelist_init(&freelist, NULL);
-
- ocf_freelist_populate(freelist, num_cls);
-
- /* now there are following cachelines on per-context lists:
- * ctx 0: 0, 1, 2
- * ctx 1: 3, 4, 5
- * ctx 2: 6, 7
- */
-
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 0);
-
- /* ctx 0: _, 1, 2
- * ctx 1: 3, 4, 5
- * ctx 2: 6, 7 */
-
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 1);
-
- /* ctx 0: _, _, 2
- * ctx 1: 3, 4, 5
- * ctx 2: 6, 7 */
-
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 2);
-
- /* ctx 0: _, _, _
- * ctx 1: 3, 4, 5
- * ctx 2: 6, 7 */
-
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 3);
-
- /* ctx 0: _, _, _
- * ctx 1: _, 4, 5
- * ctx 2: 6, 7 */
-
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 6);
-
- /* ctx 0: _, _, _
- * ctx 1: _, 4, 5
- * ctx 2: _, 7 */
-
-
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 4);
-
- /* ctx 0: _, _, _
- * ctx 1: _, _, 5
- * ctx 2: _, 7 */
-
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 7);
-
- /* ctx 0: _, _, _
- * ctx 1: _, _, 5
- * ctx 2: _, _ */
-
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 5);
-
- /* ctx 0: _, _, _,
- * ctx 1: _, _, _
- * ctx 2: _, _ */
-
- ocf_freelist_deinit(freelist);
-}
-
-static void ocf_freelist_get_cache_line_put(void **state)
-{
- unsigned num_cls = 8;
- unsigned num_ctxts = 3;
- ocf_freelist_t freelist;
- unsigned ctx_iter, cl_iter;
- ocf_cache_line_t line;
-
- print_test_description("Verify freelist cacheline put");
-
- will_return_maybe(__wrap_ocf_metadata_collision_table_entries, num_cls);
- will_return_maybe(__wrap_env_get_execution_context_count, num_ctxts);
- will_return_maybe(__wrap_metadata_test_valid_any, false);
-
- ocf_freelist_init(&freelist, NULL);
-
- ocf_freelist_populate(freelist, num_cls);
-
- /* get some clines from the freelists */
- will_return(__wrap_env_get_execution_context, 0);
- ocf_freelist_get_cache_line(freelist, &line);
- will_return(__wrap_env_get_execution_context, 0);
- ocf_freelist_get_cache_line(freelist, &line);
- will_return(__wrap_env_get_execution_context, 0);
- ocf_freelist_get_cache_line(freelist, &line);
- will_return(__wrap_env_get_execution_context, 0);
- ocf_freelist_get_cache_line(freelist, &line);
- will_return(__wrap_env_get_execution_context, 0);
- ocf_freelist_get_cache_line(freelist, &line);
-
- /* ctx 0:
- * ctx 1: 4, 5
- * ctx 2: 7 */
-
- will_return(__wrap_env_get_execution_context, 1);
- ocf_freelist_put_cache_line(freelist, 0);
-
- will_return(__wrap_env_get_execution_context, 1);
- ocf_freelist_put_cache_line(freelist, 2);
-
- will_return(__wrap_env_get_execution_context, 2);
- ocf_freelist_put_cache_line(freelist, 3);
-
- /* ctx 0:
- * ctx 1: 4, 5, 0, 2
- * ctx 2: 7, 3*/
-
- will_return(__wrap_env_get_execution_context, 1);
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 4);
-
- will_return(__wrap_env_get_execution_context, 1);
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 5);
-
- will_return(__wrap_env_get_execution_context, 1);
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 0);
-
- will_return(__wrap_env_get_execution_context, 1);
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 2);
-
- will_return(__wrap_env_get_execution_context, 2);
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 7);
-
- will_return(__wrap_env_get_execution_context, 2);
- assert(ocf_freelist_get_cache_line(freelist, &line));
- assert_int_equal(line, 3);
-
- ocf_freelist_deinit(freelist);
-}
-
-int main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(ocf_freelist_get_cache_line_get_fast),
- cmocka_unit_test(ocf_freelist_get_cache_line_get_slow),
- cmocka_unit_test(ocf_freelist_get_cache_line_put)
- };
-
- print_message("Unit test for ocf_freelist_get_cache_line\n");
-
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/unit/tests/ocf_freelist.c/ocf_freelist_init.c b/tests/unit/tests/ocf_freelist.c/ocf_freelist_init.c
deleted file mode 100644
index 255f5ad..0000000
--- a/tests/unit/tests/ocf_freelist.c/ocf_freelist_init.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * src/ocf_freelist.c
- * ocf_freelist_populate
- *
- * ocf_freelist_init
- * ocf_freelist_deinit
- *
- */
-
-#undef static
-
-#undef inline
-
-
-#include
-#include
-#include
-#include
-#include "print_desc.h"
-
-#include "ocf/ocf.h"
-#include "metadata/metadata.h"
-
-#include "ocf_freelist.c/ocf_freelist_init_generated_wraps.c"
-
-ocf_cache_line_t __wrap_ocf_metadata_collision_table_entries(ocf_cache_t cache)
-{
- function_called();
- return mock();
-}
-
-ocf_cache_line_t __wrap_env_get_execution_context_count(ocf_cache_t cache)
-{
- function_called();
- return mock();
-}
-
-static void ocf_freelist_init_test01(void **state)
-{
- unsigned num_cls = 9;
- unsigned num_ctxts = 3;
- ocf_freelist_t freelist;
- ocf_cache_t cache = 0x1234;
-
- print_test_description("Freelist initialization test");
-
- expect_function_call(__wrap_ocf_metadata_collision_table_entries);
- will_return(__wrap_ocf_metadata_collision_table_entries, num_cls);
-
- expect_function_call(__wrap_env_get_execution_context_count);
- will_return(__wrap_env_get_execution_context_count, num_ctxts);
-
- ocf_freelist_init(&freelist, cache);
- assert(freelist != NULL);
-
- ocf_freelist_deinit(freelist);
-}
-
-int main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(ocf_freelist_init_test01)
- };
-
- print_message("Unit test of ocf_freelist_init\n");
-
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/unit/tests/ocf_freelist.c/ocf_freelist_locks.c b/tests/unit/tests/ocf_freelist.c/ocf_freelist_locks.c
deleted file mode 100644
index ddedd94..0000000
--- a/tests/unit/tests/ocf_freelist.c/ocf_freelist_locks.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * src/ocf_freelist.c
- * ocf_freelist_get_cache_line
- *
- * ocf_freelist_init
- * ocf_freelist_deinit
- * ocf_freelist_populate
- * next_phys_invalid
- * ocf_freelist_unlock
- * _ocf_freelist_remove_cache_line
- * ocf_freelist_get_cache_line_fast
- * ocf_freelist_get_cache_line_slow
- * ocf_freelist_add_cache_line
- * ocf_freelist_get_cache_line_ctx
- * get_next_victim_freelist
- * ocf_freelist_put_cache_line
- *
- */
-
-#undef static
-
-#undef inline
-
-
-#include
-#include
-#include
-#include
-#include "print_desc.h"
-
-#include "ocf/ocf.h"
-#include "metadata/metadata.h"
-
-#include "ocf_freelist.c/ocf_freelist_get_put_generated_wraps.c"
-
-ocf_cache_line_t __wrap_ocf_metadata_collision_table_entries(ocf_cache_t cache)
-{
- return mock();
-}
-
-unsigned __wrap_env_get_execution_context_count(void)
-{
- return mock();
-}
-
-unsigned __wrap_env_get_execution_context(void)
-{
- return mock();
-}
-
-void __wrap_env_put_execution_context(unsigned ctx)
-{
-}
-
-/* simulate no striping */
-ocf_cache_line_t __wrap_ocf_metadata_map_phy2lg(ocf_cache_t cache, ocf_cache_line_t phy)
-{
- return phy;
-}
-
-bool __wrap_metadata_test_valid_any(ocf_cache_t cache, ocf_cache_line_t cline)
-{
- return mock();
-}
-
-void __wrap_ocf_freelist_lock(ocf_freelist_t freelist, uint32_t ctx)
-{
- function_called();
- check_expected(ctx);
-}
-
-int __wrap_ocf_freelist_trylock(ocf_freelist_t freelist, uint32_t ctx)
-{
- function_called();
- check_expected(ctx);
- return mock();
-}
-
-/* metadata partition info interface mock: */
-
-#define max_clines 100
-
-struct {
- ocf_cache_line_t prev;
- ocf_cache_line_t next;
-} partition_list[max_clines];
-
-
-void __wrap_ocf_metadata_set_partition_info(struct ocf_cache *cache,
- ocf_cache_line_t line, ocf_part_id_t part_id,
- ocf_cache_line_t next_line, ocf_cache_line_t prev_line)
-{
- assert_int_equal(part_id, PARTITION_INVALID);
- partition_list[line].prev = prev_line;
- partition_list[line].next = next_line;
-}
-
-void __wrap_ocf_metadata_get_partition_info(struct ocf_cache *cache,
- ocf_cache_line_t line, ocf_part_id_t *part_id,
- ocf_cache_line_t *next_line, ocf_cache_line_t *prev_line)
-{
- if (part_id)
- *part_id = PARTITION_INVALID;
- if (prev_line)
- *prev_line = partition_list[line].prev;
- if (next_line)
- *next_line = partition_list[line].next;
-}
-
-void __wrap_ocf_metadata_set_partition_prev(struct ocf_cache *cache,
- ocf_cache_line_t line, ocf_cache_line_t prev_line)
-{
- partition_list[line].prev = prev_line;
-}
-
-void __wrap_ocf_metadata_set_partition_next(struct ocf_cache *cache,
- ocf_cache_line_t line, ocf_cache_line_t next_line)
-{
- partition_list[line].next = next_line;
-}
-
-static void ocf_freelist_get_put_locks(void **state)
-{
- unsigned num_cls = 4;
- unsigned num_ctxts = 3;
- ocf_freelist_t freelist;
- unsigned ctx_iter, cl_iter;
- ocf_cache_line_t line;
-
- print_test_description("Verify lock/trylock sequence in get free cacheline");
-
- will_return_maybe(__wrap_ocf_metadata_collision_table_entries, num_cls);
- will_return_maybe(__wrap_env_get_execution_context_count, num_ctxts);
- will_return_maybe(__wrap_metadata_test_valid_any, false);
-
- /* simulate context 1 for the entire test duration */
- will_return_maybe(__wrap_env_get_execution_context, 1);
-
- ocf_freelist_init(&freelist, NULL);
-
- ocf_freelist_populate(freelist, num_cls);
-
- /****************************************************************/
- /* verify fast path locking - scucessfull trylock */
-
- /* ctx 0: 0, 3
- * ctx 1: 1
- * ctx 2: 2
- * slowpath next victim: 0
- */
-
- expect_value(__wrap_ocf_freelist_trylock, ctx, 1);
- expect_function_call(__wrap_ocf_freelist_trylock);
- will_return(__wrap_ocf_freelist_trylock, 0);
- ocf_freelist_get_cache_line(freelist, &line);
-
- /****************************************************************/
- /* verify fast path locking - scucessfull trylock in slowpath */
-
- /* ctx 0: 0, 3
- * ctx 1:
- * ctx 2: 2
- * slowpath next victim: 0 */
-
- /* we expect trylock for context 0, since context 1 has empty list */
- expect_value(__wrap_ocf_freelist_trylock, ctx, 0);
- expect_function_call(__wrap_ocf_freelist_trylock);
- will_return(__wrap_ocf_freelist_trylock, 0);
- ocf_freelist_get_cache_line(freelist, &line);
-
- /****************************************************************/
- /* verify fast path locking - trylock failure in slowpath */
-
- /* ctx 0: 3
- * ctx 1:
- * ctx 2: 2
- * slowpath next victim: 1 */
-
- /* fastpath will fail immediately - context 1 list is empty */
- /* next slowpath victim context (1) is empty - will move to ctx 2 */
- /* so now we expect trylock for context no 2 - injecting error here*/
- expect_value(__wrap_ocf_freelist_trylock, ctx, 2);
- expect_function_call(__wrap_ocf_freelist_trylock);
- will_return(__wrap_ocf_freelist_trylock, 1);
-
- /* slowpath will attempt to trylock next non-empty context - 0
- * - injecting error here as well */
- expect_value(__wrap_ocf_freelist_trylock, ctx, 0);
- expect_function_call(__wrap_ocf_freelist_trylock);
- will_return(__wrap_ocf_freelist_trylock, 1);
-
- /* slowpath trylock loop failed - expecting full lock */
- expect_value(__wrap_ocf_freelist_lock, ctx, 2);
- expect_function_call(__wrap_ocf_freelist_lock);
-
- /* execute freelist_get_cache_line */
- ocf_freelist_get_cache_line(freelist, &line);
-
- /****************************************************************/
-
- ocf_freelist_deinit(freelist);
-}
-
-int main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(ocf_freelist_get_put_locks)
- };
-
- print_message("Unit test for ocf_freelist_get_cache_line locking\n");
-
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/unit/tests/ocf_freelist.c/ocf_freelist_populate.c b/tests/unit/tests/ocf_freelist.c/ocf_freelist_populate.c
deleted file mode 100644
index 235800e..0000000
--- a/tests/unit/tests/ocf_freelist.c/ocf_freelist_populate.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * src/ocf_freelist.c
- * ocf_freelist_populate
- *
- * ocf_freelist_init
- * ocf_freelist_deinit
- * ocf_freelist_populate
- * next_phys_invalid
- *
- */
-
-#undef static
-
-#undef inline
-
-
-#include
-#include
-#include
-#include
-#include "print_desc.h"
-
-#include "ocf/ocf.h"
-#include "metadata/metadata.h"
-
-#include "ocf_freelist.c/ocf_freelist_populate_generated_wraps.c"
-
-ocf_cache_line_t __wrap_ocf_metadata_collision_table_entries(ocf_cache_t cache)
-{
- return mock();
-}
-
-ocf_cache_line_t __wrap_env_get_execution_context_count(ocf_cache_t cache)
-{
- return mock();
-}
-
-/* simulate no striping */
-ocf_cache_line_t __wrap_ocf_metadata_map_phy2lg(ocf_cache_t cache, ocf_cache_line_t phy)
-{
- return phy;
-}
-
-bool __wrap_metadata_test_valid_any(ocf_cache_t cache, ocf_cache_line_t cline)
-{
- return mock();
-}
-
-void __wrap_ocf_metadata_set_partition_info(struct ocf_cache *cache,
- ocf_cache_line_t line, ocf_part_id_t part_id,
- ocf_cache_line_t next_line, ocf_cache_line_t prev_line)
-{
- print_message("%s %u %u %u\n", __func__, prev_line, line, next_line);
- check_expected(line);
- check_expected(part_id);
- check_expected(next_line);
- check_expected(prev_line);
-}
-
-#define expect_set_info(curr, part, next, prev) \
- expect_value(__wrap_ocf_metadata_set_partition_info, line, curr); \
- expect_value(__wrap_ocf_metadata_set_partition_info, part_id, part); \
- expect_value(__wrap_ocf_metadata_set_partition_info, next_line, next); \
- expect_value(__wrap_ocf_metadata_set_partition_info, prev_line, prev);
-
-static void ocf_freelist_populate_test01(void **state)
-{
- unsigned num_cls = 8;
- unsigned num_ctxts = 3;
- ocf_freelist_t freelist;
- unsigned ctx_iter, cl_iter;
-
- print_test_description("Verify proper set_partition_info order and arguments - empty cache");
-
- will_return_maybe(__wrap_ocf_metadata_collision_table_entries, num_cls);
- will_return_maybe(__wrap_env_get_execution_context_count, num_ctxts);
- will_return_maybe(__wrap_metadata_test_valid_any, false);
-
- ocf_freelist_init(&freelist, NULL);
-
- expect_set_info(0, PARTITION_INVALID, 1 , num_cls);
- expect_set_info(1, PARTITION_INVALID, 2 , 0);
- expect_set_info(2, PARTITION_INVALID, num_cls, 1);
- expect_set_info(3, PARTITION_INVALID, 4 , num_cls);
- expect_set_info(4, PARTITION_INVALID, 5 , 3);
- expect_set_info(5, PARTITION_INVALID, num_cls, 4);
- expect_set_info(6, PARTITION_INVALID, 7 , num_cls);
- expect_set_info(7, PARTITION_INVALID, num_cls, 6);
-
- ocf_freelist_populate(freelist, num_cls);
-
- ocf_freelist_deinit(freelist);
-}
-
-static void ocf_freelist_populate_test02(void **state)
-{
- unsigned num_cls = 8;
- unsigned num_ctxts = 3;
- ocf_freelist_t freelist;
- unsigned ctx_iter, cl_iter;
-
- print_test_description("Verify proper set_partition_info order and arguments - some valid clines");
-
- will_return_maybe(__wrap_ocf_metadata_collision_table_entries, num_cls);
- will_return_maybe(__wrap_env_get_execution_context_count, num_ctxts);
-
- ocf_freelist_init(&freelist, NULL);
-
- /* simulate only cachelines 2, 3, 4, 7 invalid */
- will_return(__wrap_metadata_test_valid_any, true);
- will_return(__wrap_metadata_test_valid_any, true);
- will_return(__wrap_metadata_test_valid_any, false);
- will_return(__wrap_metadata_test_valid_any, false);
- will_return(__wrap_metadata_test_valid_any, false);
- will_return(__wrap_metadata_test_valid_any, true);
- will_return(__wrap_metadata_test_valid_any, true);
- will_return(__wrap_metadata_test_valid_any, false);
-
- expect_set_info(2, PARTITION_INVALID, 3 , num_cls);
- expect_set_info(3, PARTITION_INVALID, num_cls, 2);
- expect_set_info(4, PARTITION_INVALID, num_cls, num_cls);
- expect_set_info(7, PARTITION_INVALID, num_cls, num_cls);
-
- ocf_freelist_populate(freelist, 4);
-
- ocf_freelist_deinit(freelist);
-}
-int main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(ocf_freelist_populate_test01),
- cmocka_unit_test(ocf_freelist_populate_test02)
- };
-
- print_message("Unit test of src/ocf_freelist.c\n");
-
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/unit/tests/eviction/lru.c/lru.c b/tests/unit/tests/ocf_lru.c/lru.c
similarity index 91%
rename from tests/unit/tests/eviction/lru.c/lru.c
rename to tests/unit/tests/ocf_lru.c/lru.c
index f3d43ec..563a7ec 100644
--- a/tests/unit/tests/eviction/lru.c/lru.c
+++ b/tests/unit/tests/ocf_lru.c/lru.c
@@ -1,5 +1,5 @@
/*
- * src/eviction/lru.c
+ * src/ocf_lru.c
* _lru_init
*
* update_lru_head
@@ -23,8 +23,8 @@
#include
#include "print_desc.h"
-#include "eviction.h"
-#include "lru.h"
+#include "ocf_space.h"
+#include "ocf_lru.h"
#include "ops.h"
#include "../utils/utils_cleaner.h"
#include "../utils/utils_cache_line.h"
@@ -33,14 +33,19 @@
#include "../engine/engine_zero.h"
#include "../ocf_request.h"
-#include "eviction/lru.c/lru_generated_wraps.c"
+#include "ocf_lru.c/lru_generated_wraps.c"
#define META_COUNT 128
-static union eviction_policy_meta meta[META_COUNT];
+static struct ocf_lru_meta meta[META_COUNT];
-union eviction_policy_meta*
-__wrap_ocf_metadata_get_eviction_policy(ocf_cache_t cache, ocf_cache_line_t line)
+struct ocf_cache_line_concurrency *__wrap_ocf_cache_line_concurrency(ocf_cache_t cache)
+{
+ return NULL;
+}
+
+struct ocf_lru_meta*
+__wrap_ocf_metadata_get_lru(ocf_cache_t cache, ocf_cache_line_t line)
{
assert (line < META_COUNT);
return &meta[line];
@@ -54,7 +59,7 @@ static void _lru_init_test01(void **state)
print_test_description("test init\n");
- _lru_init(&l, end_marker);
+ _lru_init(&l, true);
assert_int_equal(l.num_hot, 0);
assert_int_equal(l.num_nodes, 0);
@@ -71,12 +76,12 @@ static void check_hot_elems(struct ocf_lru_list *l)
unsigned curr = l->head;
for (i = 0; i < l->num_hot; i++) {
- assert_int_equal(meta[curr].lru.hot, 1);
- curr = meta[curr].lru.next;
+ assert_int_equal(meta[curr].hot, 1);
+ curr = meta[curr].next;
}
for (i = l->num_hot; i < l->num_nodes; i++) {
- assert_int_equal(meta[curr].lru.hot, 0);
- curr = meta[curr].lru.next;
+ assert_int_equal(meta[curr].hot, 0);
+ curr = meta[curr].next;
}
}
@@ -89,7 +94,7 @@ static void _lru_init_test02(void **state)
print_test_description("test add\n");
- _lru_init(&l, end_marker);
+ _lru_init(&l, true);
for (i = 1; i <= 8; i++)
{
@@ -114,7 +119,7 @@ static void _lru_init_test03(void **state)
print_test_description("remove head\n");
- _lru_init(&l, end_marker);
+ _lru_init(&l, true);
for (i = 1; i <= 8; i++) {
add_lru_head(NULL, &l, i, end_marker);
@@ -150,7 +155,7 @@ static void _lru_init_test04(void **state)
print_test_description("remove tail\n");
- _lru_init(&l, end_marker);
+ _lru_init(&l, true);
for (i = 1; i <= 8; i++) {
add_lru_head(NULL, &l, i, end_marker);
@@ -188,7 +193,7 @@ static void _lru_init_test05(void **state)
print_test_description("remove last hot\n");
- _lru_init(&l, end_marker);
+ _lru_init(&l, true);
for (i = 1; i <= 8; i++) {
add_lru_head(NULL, &l, i, end_marker);
@@ -235,7 +240,7 @@ static void _lru_init_test06(void **state)
print_test_description("remove middle hot\n");
- _lru_init(&l, end_marker);
+ _lru_init(&l, true);
for (i = 1; i <= 8; i++) {
add_lru_head(NULL, &l, i, end_marker);
diff --git a/tests/unit/tests/eviction/lru.c/lru_iter.c b/tests/unit/tests/ocf_lru.c/lru_iter.c
similarity index 74%
rename from tests/unit/tests/eviction/lru.c/lru_iter.c
rename to tests/unit/tests/ocf_lru.c/lru_iter.c
index dbc5664..5f7a8ab 100644
--- a/tests/unit/tests/eviction/lru.c/lru_iter.c
+++ b/tests/unit/tests/ocf_lru.c/lru_iter.c
@@ -1,14 +1,14 @@
/*
- * src/eviction/lru.c
+ * src/ocf_lru.c
* lru_iter_next
*
* INSERT HERE LIST OF FUNCTIONS YOU WANT TO LEAVE
* ONE FUNCTION PER LINE
* lru_iter_init
- * _lru_next_evp
- * _lru_evp_is_empty
- * _lru_evp_set_empty
- * _lru_evp_all_empty
+ * _lru_next_lru
+ * _lru_lru_is_empty
+ * _lru_lru_set_empty
+ * _lru_lru_all_empty
* ocf_rotate_right
* lru_iter_eviction_next
* lru_iter_cleaning_next
@@ -26,9 +26,8 @@
#include
#include "print_desc.h"
-#include "eviction.h"
-#include "lru.h"
-#include "ops.h"
+#include "ocf_space.h"
+#include "ocf_lru.h"
#include "../utils/utils_cleaner.h"
#include "../utils/utils_cache_line.h"
#include "../concurrency/ocf_concurrency.h"
@@ -36,11 +35,16 @@
#include "../engine/engine_zero.h"
#include "../ocf_request.h"
-#include "eviction/lru.c/lru_iter_generated_wraps.c"
+#include "ocf_lru.c/lru_iter_generated_wraps.c"
//#define DEBUG
-ocf_cache_line_t test_cases[10 * OCF_NUM_EVICTION_LISTS][OCF_NUM_EVICTION_LISTS][20];
+struct ocf_cache_line_concurrency *__wrap_ocf_cache_line_concurrency(ocf_cache_t cache)
+{
+ return NULL;
+}
+
+ocf_cache_line_t test_cases[10 * OCF_NUM_LRU_LISTS][OCF_NUM_LRU_LISTS][20];
unsigned num_cases = 20;
void write_test_case_description(void)
@@ -49,21 +53,21 @@ void write_test_case_description(void)
unsigned test_case = 0;
// case 0 - all lists empty
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++) {
test_cases[0][i][test_case] = -1;
}
// case 1 - all lists with single element
test_case++;
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++) {
test_cases[0][i][test_case] = 10 * i;
test_cases[1][i][test_case] = -1;
}
// case 2 - all lists have between 1 and 5 elements, increasingly
test_case++;
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
- unsigned num_elements = 1 + i / (OCF_NUM_EVICTION_LISTS / 4);
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++) {
+ unsigned num_elements = 1 + i / (OCF_NUM_LRU_LISTS / 4);
for (j = 0; j < num_elements; j++)
test_cases[j][i][test_case] = 10 * i + j;
@@ -72,7 +76,7 @@ void write_test_case_description(void)
// case 3 - all lists have between 1 and 5 elements, modulo index
test_case++;
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++) {
unsigned num_elements = 1 + (i % 5);
for (j = 0; j < num_elements; j++)
@@ -82,8 +86,8 @@ void write_test_case_description(void)
// case 4 - all lists have between 0 and 4 elements, increasingly
test_case++;
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
- unsigned num_elements = i / (OCF_NUM_EVICTION_LISTS / 4);
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++) {
+ unsigned num_elements = i / (OCF_NUM_LRU_LISTS / 4);
for (j = 0; j < num_elements; j++)
test_cases[j][i][test_case] = 10 * i + j;
@@ -92,7 +96,7 @@ void write_test_case_description(void)
// case 5 - all lists have between 0 and 4 elements, modulo index
test_case++;
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++) {
unsigned num_elements = (i % 5);
for (j = 0; j < num_elements; j++)
@@ -102,41 +106,41 @@ void write_test_case_description(void)
// case 6 - list length increasing by 1 from 0
test_case++;
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++) {
unsigned num_elements = i;
for (j = 0; j < num_elements; j++)
- test_cases[j][i][test_case] = OCF_NUM_EVICTION_LISTS * i + j;
+ test_cases[j][i][test_case] = OCF_NUM_LRU_LISTS * i + j;
test_cases[j][i][test_case] = -1;
}
// case 7 - list length increasing by 1 from 1
test_case++;
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++) {
unsigned num_elements = i + 1;
for (j = 0; j < num_elements; j++)
- test_cases[j][i][test_case] = 2 * OCF_NUM_EVICTION_LISTS * i + j;
+ test_cases[j][i][test_case] = 2 * OCF_NUM_LRU_LISTS * i + j;
test_cases[j][i][test_case] = -1;
}
// case 8 - list length increasing by 4 from 0
test_case++;
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++) {
unsigned num_elements = 4 * i;
for (j = 0; j < num_elements; j++)
- test_cases[j][i][test_case] = 4 * OCF_NUM_EVICTION_LISTS * i + j;
+ test_cases[j][i][test_case] = 4 * OCF_NUM_LRU_LISTS * i + j;
test_cases[j][i][test_case] = -1;
}
// case 9 - list length increasing by 4 from 1
test_case++;
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++) {
unsigned num_elements = 4 * i + 1;
for (j = 0; j < num_elements; j++)
- test_cases[j][i][test_case] = 5 * OCF_NUM_EVICTION_LISTS * i + j;
+ test_cases[j][i][test_case] = 5 * OCF_NUM_LRU_LISTS * i + j;
test_cases[j][i][test_case] = -1;
}
@@ -146,8 +150,8 @@ void write_test_case_description(void)
while(test_case < 2 * (l + 1)) {
unsigned matching_case = test_case - l - 1;
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
- unsigned curr_list = (i + 4) % OCF_NUM_EVICTION_LISTS;
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++) {
+ unsigned curr_list = (i + 4) % OCF_NUM_LRU_LISTS;
j = 0;
while(test_cases[j][i][matching_case] != -1) {
test_cases[j][curr_list][test_case] =
@@ -160,13 +164,13 @@ void write_test_case_description(void)
}
/* transform cacheline numbers so that they remain unique but have
- * assignment to list modulo OCF_NUM_EVICTION_LISTS */
+ * assignment to list modulo OCF_NUM_LRU_LISTS */
for (test_case = 0; test_case < num_cases; test_case++) {
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++) {
j = 0;
while (test_cases[j][i][test_case] != -1) {
test_cases[j][i][test_case] = test_cases[j][i][test_case] *
- OCF_NUM_EVICTION_LISTS + i;
+ OCF_NUM_LRU_LISTS + i;
j++;
}
}
@@ -181,7 +185,7 @@ void write_test_case_description(void)
for (test_case = 0; test_case < num_cases; test_case++) {
print_message("test case no %d\n", test_case);
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++) {
print_message("list %02u: ", i);
j = 0;
while (test_cases[j][i][test_case] != -1) {
@@ -199,12 +203,12 @@ unsigned current_case;
struct ocf_lru_list list;
-struct ocf_lru_list *__wrap_evp_lru_get_list(struct ocf_user_part *part,
- uint32_t evp, bool clean)
+struct ocf_lru_list *__wrap_ocf_lru_get_list(struct ocf_user_part *user_part,
+ uint32_t lru, bool clean)
{
unsigned i = 0;
- while (test_cases[i][evp][current_case] != -1)
+ while (test_cases[i][lru][current_case] != -1)
i++;
if (i == 0) {
@@ -212,53 +216,53 @@ struct ocf_lru_list *__wrap_evp_lru_get_list(struct ocf_user_part *part,
list.tail = -1;
list.num_nodes = 0;
} else {
- list.head = test_cases[0][evp][current_case];
- list.tail = test_cases[i - 1][evp][current_case];
+ list.head = test_cases[0][lru][current_case];
+ list.tail = test_cases[i - 1][lru][current_case];
list.num_nodes = i;
}
#ifdef DEBUG
- print_message("list for case %u evp %u: head: %u tail %u elems %u\n",
- current_case, evp, list.head, list.tail, list.num_nodes);
+ print_message("list for case %u lru %u: head: %u tail %u elems %u\n",
+ current_case, lru, list.head, list.tail, list.num_nodes);
#endif
return &list;
}
-inline struct ocf_lru_list *__wrap_evp_get_cline_list(ocf_cache_t cache,
+inline struct ocf_lru_list *__wrap_lru_get_cline_list(ocf_cache_t cache,
ocf_cache_line_t cline)
{
- return __wrap_evp_lru_get_list(NULL, cline % OCF_NUM_EVICTION_LISTS, true);
+ return __wrap_ocf_lru_get_list(NULL, cline % OCF_NUM_LRU_LISTS, true);
}
-union eviction_policy_meta policy;
+struct ocf_lru_meta g_lru_meta;
-union eviction_policy_meta *__wrap_ocf_metadata_get_eviction_policy(
+struct ocf_lru_meta *__wrap_ocf_metadata_get_lru(
struct ocf_cache *cache, ocf_cache_line_t line)
{
unsigned i, j;
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++)
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++)
{
j = 0;
while (test_cases[j][i][current_case] != -1) {
if (test_cases[j][i][current_case] == line) {
if (j == 0) {
- policy.lru.prev = -1;
+ g_lru_meta.prev = -1;
} else {
- policy.lru.prev =
+ g_lru_meta.prev =
test_cases[j - 1][i][current_case];
}
- policy.lru.next = test_cases[j + 1][i][current_case];
+ g_lru_meta.next = test_cases[j + 1][i][current_case];
#ifdef DEBUG
print_message("[%u] next %u prev %u\n",
- line, policy.lru.next,
- policy.lru.prev);
+ line, g_lru_meta.next,
+ g_lru_meta.prev);
#endif
- return &policy;
+ return &g_lru_meta;
}
j++;
}
@@ -276,7 +280,7 @@ void __wrap_add_lru_head(ocf_cache_t cache,
unsigned int collision_index)
{
unsigned list_head = list->head;
- unsigned i, j = collision_index % OCF_NUM_EVICTION_LISTS;
+ unsigned i, j = collision_index % OCF_NUM_LRU_LISTS;
i = 1;
while (test_cases[i][j][current_case] != -1)
@@ -290,7 +294,7 @@ void __wrap_add_lru_head(ocf_cache_t cache,
test_cases[0][j][current_case] = collision_index;
#ifdef DEBUG
- print_message("case %u evp %u head set to %u\n", current_case, j, collision_index);
+ print_message("case %u lru %u head set to %u\n", current_case, j, collision_index);
#endif
}
@@ -303,7 +307,7 @@ void __wrap_remove_lru_list(ocf_cache_t cache,
unsigned i, j;
found = false;
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++)
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++)
{
j = 0;
@@ -324,7 +328,7 @@ void __wrap_remove_lru_list(ocf_cache_t cache,
assert(found);
#ifdef DEBUG
- print_message("case %u removed %u from evp %u\n", current_case, collision_index, i);
+ print_message("case %u removed %u from lru %u\n", current_case, collision_index, i);
#endif
}
@@ -335,28 +339,33 @@ bool __wrap__lru_lock(struct ocf_lru_iter *iter,
return true;
}
-bool __wrap__lru_trylock_cacheline(struct ocf_lru_iter *iter,
- ocf_cache_line_t cline)
+bool __wrap_ocf_cache_line_try_lock_rd(struct ocf_cache_line_concurrency *c,
+ ocf_cache_line_t line)
{
return true;
}
+bool __wrap_ocf_cache_line_try_lock_wr(struct ocf_cache_line_concurrency *c,
+ ocf_cache_line_t line)
+{
+ return false;
+}
static void _lru_run_test(unsigned test_case)
{
unsigned start_pos;
current_case = test_case;
- for (start_pos = 0; start_pos < OCF_NUM_EVICTION_LISTS; start_pos++)
+ for (start_pos = 0; start_pos < OCF_NUM_LRU_LISTS; start_pos++)
{
struct ocf_lru_iter iter;
ocf_cache_line_t cache_line, expected_cache_line;
- unsigned curr_evp = start_pos;
- unsigned pos[OCF_NUM_EVICTION_LISTS];
+ unsigned curr_lru = start_pos;
+ unsigned pos[OCF_NUM_LRU_LISTS];
unsigned i;
write_test_case_description();
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++)
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++)
{
pos[i] = -1;
while(test_cases[pos[i] + 1][i][test_case] != -1)
@@ -368,26 +377,26 @@ static void _lru_run_test(unsigned test_case)
do {
/* check what is expected to be returned from iterator */
- if (pos[curr_evp] == -1) {
+ if (pos[curr_lru] == -1) {
i = 1;
- while (i < OCF_NUM_EVICTION_LISTS &&
- pos[(curr_evp + i) % OCF_NUM_EVICTION_LISTS]
+ while (i < OCF_NUM_LRU_LISTS &&
+ pos[(curr_lru + i) % OCF_NUM_LRU_LISTS]
== -1) {
i++;
}
- if (i == OCF_NUM_EVICTION_LISTS) {
+ if (i == OCF_NUM_LRU_LISTS) {
/* reached end of lists */
expected_cache_line = -1;
} else {
- curr_evp = (curr_evp + i) % OCF_NUM_EVICTION_LISTS;
- expected_cache_line = test_cases[pos[curr_evp]]
- [curr_evp][test_case];
- pos[curr_evp]--;
+ curr_lru = (curr_lru + i) % OCF_NUM_LRU_LISTS;
+ expected_cache_line = test_cases[pos[curr_lru]]
+ [curr_lru][test_case];
+ pos[curr_lru]--;
}
} else {
- expected_cache_line = test_cases[pos[curr_evp]]
- [curr_evp][test_case];
- pos[curr_evp]--;
+ expected_cache_line = test_cases[pos[curr_lru]]
+ [curr_lru][test_case];
+ pos[curr_lru]--;
}
/* get cacheline from iterator */
@@ -395,11 +404,11 @@ static void _lru_run_test(unsigned test_case)
assert_int_equal(cache_line, expected_cache_line);
- curr_evp = (curr_evp + 1) % OCF_NUM_EVICTION_LISTS;
+ curr_lru = (curr_lru + 1) % OCF_NUM_LRU_LISTS;
} while (cache_line != -1);
/* make sure all cachelines are visited */
- for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++)
+ for (i = 0; i < OCF_NUM_LRU_LISTS; i++)
{
assert_int_equal((unsigned)-1, pos[i]);
}
diff --git a/tests/unit/tests/eviction/eviction.c/eviction.c b/tests/unit/tests/ocf_space.c/ocf_space.c
similarity index 66%
rename from tests/unit/tests/eviction/eviction.c/eviction.c
rename to tests/unit/tests/ocf_space.c/ocf_space.c
index 076c721..b257be2 100644
--- a/tests/unit/tests/eviction/eviction.c/eviction.c
+++ b/tests/unit/tests/ocf_space.c/ocf_space.c
@@ -1,8 +1,8 @@
/*
- * src/eviction/eviction.c
- * ocf_evict_do
+ * src/ocf_space.c
+ * ocf_remap_do
*
- ocf_evict_partitions
+ ocf_evict_user_partitions
*
*/
@@ -17,55 +17,56 @@
#include
#include "print_desc.h"
-#include "eviction.h"
-#include "ops.h"
-#include "../utils/utils_part.h"
+#include "ocf_space.h"
+#include "../utils/utils_user_part.h"
-#include "eviction/eviction.c/eviction_generated_wraps.c"
+#include "ocf_space.c/ocf_space_generated_wraps.c"
struct test_cache
{
struct ocf_cache cache;
- struct ocf_user_part_config part[OCF_IO_CLASS_MAX];
- uint32_t overflow[OCF_IO_CLASS_MAX];
- uint32_t evictable[OCF_IO_CLASS_MAX];
+ struct ocf_user_part_config part[OCF_USER_IO_CLASS_MAX];
+ struct ocf_part_runtime runtime[OCF_USER_IO_CLASS_MAX];
+ uint32_t overflow[OCF_USER_IO_CLASS_MAX];
+ uint32_t evictable[OCF_USER_IO_CLASS_MAX];
uint32_t req_unmapped;
};
-bool __wrap_ocf_eviction_can_evict(ocf_cache_t cache)
+uint32_t __wrap_ocf_lru_num_free(ocf_cache_t cache)
{
- return true;
+ return 0;
}
-uint32_t __wrap_ocf_part_overflow_size(struct ocf_cache *cache,
- struct ocf_user_part *part)
+uint32_t __wrap_ocf_user_part_overflow_size(struct ocf_cache *cache,
+ struct ocf_user_part *user_part)
{
struct test_cache* tcache = cache;
- return tcache->overflow[part->id];
+ return tcache->overflow[user_part->part.id];
}
uint32_t __wrap_ocf_evict_calculate(ocf_cache_t cache,
- struct ocf_user_part *part, uint32_t to_evict, bool roundup)
+ struct ocf_user_part *user_part, uint32_t to_evict, bool roundup)
{
struct test_cache* tcache = cache;
- return min(tcache->evictable[part->id], to_evict);
+ return min(tcache->evictable[user_part->part.id], to_evict);
}
-uint32_t __wrap_ocf_eviction_need_space(struct ocf_cache *cache,
- ocf_queue_t io_queue, struct ocf_user_part *part,
- uint32_t clines)
+uint32_t __wrap_ocf_lru_req_clines(struct ocf_request *req,
+ struct ocf_part *src_part, uint32_t cline_no)
{
- struct test_cache *tcache = (struct test_cache *)cache;
- unsigned overflown_consumed = min(clines, tcache->overflow[part->id]);
+ struct test_cache *tcache = (struct test_cache *)req->cache;
+ unsigned overflown_consumed;
- tcache->overflow[part->id] -= overflown_consumed;
- tcache->evictable[part->id] -= clines;
- tcache->req_unmapped -= clines;
+ overflown_consumed = min(cline_no, tcache->overflow[src_part->id]);
- check_expected(part);
- check_expected(clines);
+ tcache->overflow[src_part->id] -= overflown_consumed;
+ tcache->evictable[src_part->id] -= cline_no;
+ tcache->req_unmapped -= cline_no;
+
+ check_expected(src_part);
+ check_expected(cline_no);
function_called();
return mock();
@@ -94,7 +95,7 @@ bool ocf_cache_is_device_attached(ocf_cache_t cache)
/* FIXME: copy-pasted from OCF */
-int ocf_part_lst_cmp_valid(struct ocf_cache *cache,
+int ocf_user_part_lst_cmp_valid(struct ocf_cache *cache,
struct ocf_lst_entry *e1, struct ocf_lst_entry *e2)
{
struct ocf_user_part *p1 = container_of(e1, struct ocf_user_part,
@@ -102,10 +103,11 @@ int ocf_part_lst_cmp_valid(struct ocf_cache *cache,
struct ocf_user_part *p2 = container_of(e2, struct ocf_user_part,
lst_valid);
size_t p1_size = ocf_cache_is_device_attached(cache) ?
- p1->runtime->curr_size : 0;
+ env_atomic_read(&p1->part.runtime->curr_size)
+ : 0;
size_t p2_size = ocf_cache_is_device_attached(cache) ?
- p2->runtime->curr_size : 0;
-
+ env_atomic_read(&p2->part.runtime->curr_size)
+ : 0;
int v1 = p1->config->priority;
int v2 = p2->config->priority;
@@ -154,6 +156,7 @@ int ocf_part_lst_cmp_valid(struct ocf_cache *cache,
return v2 - v1;
}
+
static struct ocf_lst_entry *_list_getter(
struct ocf_cache *cache, ocf_cache_line_t idx)
{
@@ -166,18 +169,18 @@ static void init_part_list(struct test_cache *tcache)
{
unsigned i;
- for (i = 0; i < OCF_IO_CLASS_MAX; i++) {
- tcache->cache.user_parts[i].id = i;
+ for (i = 0; i < OCF_USER_IO_CLASS_MAX; i++) {
+ tcache->cache.user_parts[i].part.id = i;
tcache->cache.user_parts[i].config = &tcache->part[i];
tcache->cache.user_parts[i].config->priority = i+1;
tcache->cache.user_parts[i].config->flags.eviction = 1;
}
- ocf_lst_init((ocf_cache_t)tcache, &tcache->cache.lst_part, OCF_IO_CLASS_MAX,
- _list_getter, ocf_part_lst_cmp_valid);
- for (i = 0; i < OCF_IO_CLASS_MAX; i++) {
- ocf_lst_init_entry(&tcache->cache.lst_part, &tcache->cache.user_parts[i].lst_valid);
- ocf_lst_add_tail(&tcache->cache.lst_part, i);
+ ocf_lst_init((ocf_cache_t)tcache, &tcache->cache.user_part_list, OCF_USER_IO_CLASS_MAX,
+ _list_getter, ocf_user_part_lst_cmp_valid);
+ for (i = 0; i < OCF_USER_IO_CLASS_MAX; i++) {
+ ocf_lst_init_entry(&tcache->cache.user_part_list, &tcache->cache.user_parts[i].lst_valid);
+ ocf_lst_add_tail(&tcache->cache.user_part_list, i);
}
}
@@ -190,13 +193,13 @@ uint32_t __wrap_ocf_engine_unmapped_count(struct ocf_request *req)
#define _expect_evict_call(tcache, part_id, req_count, ret_count) \
do { \
- expect_value(__wrap_ocf_eviction_need_space, part, &tcache.cache.user_parts[part_id]); \
- expect_value(__wrap_ocf_eviction_need_space, clines, req_count); \
- expect_function_call(__wrap_ocf_eviction_need_space); \
- will_return(__wrap_ocf_eviction_need_space, ret_count); \
+ expect_value(__wrap_ocf_lru_req_clines, src_part, &tcache.cache.user_parts[part_id].part); \
+ expect_value(__wrap_ocf_lru_req_clines, cline_no, req_count); \
+ expect_function_call(__wrap_ocf_lru_req_clines); \
+ will_return(__wrap_ocf_lru_req_clines, ret_count); \
} while (false);
-static void ocf_evict_do_test01(void **state)
+static void ocf_remap_do_test01(void **state)
{
struct test_cache tcache = {};
struct ocf_request req = {.cache = &tcache.cache, .part_id = 0 };
@@ -210,11 +213,11 @@ static void ocf_evict_do_test01(void **state)
tcache.req_unmapped = 50;
_expect_evict_call(tcache, 10, 50, 50);
- evicted = ocf_evict_do(&req);
+ evicted = ocf_remap_do(&req);
assert_int_equal(evicted, 50);
}
-static void ocf_evict_do_test02(void **state)
+static void ocf_remap_do_test02(void **state)
{
struct test_cache tcache = {};
struct ocf_request req = {.cache = &tcache.cache, .part_id = 0 };
@@ -231,11 +234,11 @@ static void ocf_evict_do_test02(void **state)
_expect_evict_call(tcache, 10, 50, 50);
- evicted = ocf_evict_do(&req);
+ evicted = ocf_remap_do(&req);
assert_int_equal(evicted, 50);
}
-static void ocf_evict_do_test03(void **state)
+static void ocf_remap_do_test03(void **state)
{
struct test_cache tcache = {};
struct ocf_request req = {.cache = &tcache.cache, .part_id = 0 };
@@ -257,11 +260,11 @@ static void ocf_evict_do_test03(void **state)
_expect_evict_call(tcache, 16, 100, 100);
_expect_evict_call(tcache, 17, 50, 50);
- evicted = ocf_evict_do(&req);
+ evicted = ocf_remap_do(&req);
assert_int_equal(evicted, 350);
}
-static void ocf_evict_do_test04(void **state)
+static void ocf_remap_do_test04(void **state)
{
struct test_cache tcache = {};
struct ocf_request req = {.cache = &tcache.cache, .part_id = 0 };
@@ -291,16 +294,16 @@ static void ocf_evict_do_test04(void **state)
_expect_evict_call(tcache, 16, 100, 100);
_expect_evict_call(tcache, 17, 80, 80);
- evicted = ocf_evict_do(&req);
+ evicted = ocf_remap_do(&req);
assert_int_equal(evicted, 580);
}
int main(void)
{
const struct CMUnitTest tests[] = {
- cmocka_unit_test(ocf_evict_do_test01),
- cmocka_unit_test(ocf_evict_do_test02),
- cmocka_unit_test(ocf_evict_do_test03),
- cmocka_unit_test(ocf_evict_do_test04)
+ cmocka_unit_test(ocf_remap_do_test01),
+ cmocka_unit_test(ocf_remap_do_test02),
+ cmocka_unit_test(ocf_remap_do_test03),
+ cmocka_unit_test(ocf_remap_do_test04)
};
return cmocka_run_group_tests(tests, NULL, NULL);