lru refactor
rearanging lru implementation for easier journaling Signed-off-by: Adam Rutkowski <adam.j.rutkowski@intel.com>
This commit is contained in:
parent
c8268245ba
commit
1e1955b833
@ -1167,7 +1167,7 @@ static void _recovery_rebuild_cline_metadata(ocf_cache_t cache,
|
|||||||
|
|
||||||
ocf_lru_init_cline(cache, cache_line);
|
ocf_lru_init_cline(cache, cache_line);
|
||||||
|
|
||||||
ocf_lru_hot_cline(cache, cache_line);
|
ocf_lru_add(cache, cache_line);
|
||||||
|
|
||||||
env_atomic_inc(&core->runtime_meta->cached_clines);
|
env_atomic_inc(&core->runtime_meta->cached_clines);
|
||||||
env_atomic_inc(&core->runtime_meta->
|
env_atomic_inc(&core->runtime_meta->
|
||||||
|
334
src/ocf_lru.c
334
src/ocf_lru.c
@ -16,11 +16,70 @@
|
|||||||
|
|
||||||
static const ocf_cache_line_t end_marker = (ocf_cache_line_t)-1;
|
static const ocf_cache_line_t end_marker = (ocf_cache_line_t)-1;
|
||||||
|
|
||||||
|
/* update list last_hot index. returns pivot element (the one for which hot
|
||||||
|
* status effectively changes during balancing). */
|
||||||
|
static inline ocf_cache_line_t balance_update_last_hot(ocf_cache_t cache,
|
||||||
|
struct ocf_lru_list *list, int change)
|
||||||
|
{
|
||||||
|
ocf_cache_line_t last_hot_new, last_hot_old;
|
||||||
|
|
||||||
|
last_hot_old = list->last_hot;
|
||||||
|
|
||||||
|
if (change > 0) {
|
||||||
|
ENV_BUG_ON(change != 1);
|
||||||
|
|
||||||
|
if (unlikely(list->last_hot == end_marker)) {
|
||||||
|
last_hot_new = list->head;
|
||||||
|
} else {
|
||||||
|
last_hot_new = ocf_metadata_get_lru(cache,
|
||||||
|
list->last_hot)->next;
|
||||||
|
ENV_BUG_ON(last_hot_new == end_marker);
|
||||||
|
}
|
||||||
|
} else if (change < 0) {
|
||||||
|
ENV_BUG_ON(change != -1);
|
||||||
|
ENV_BUG_ON(list->last_hot == end_marker);
|
||||||
|
|
||||||
|
last_hot_new = ocf_metadata_get_lru(cache, list->last_hot)->prev;
|
||||||
|
} else {
|
||||||
|
last_hot_new = list->last_hot;
|
||||||
|
}
|
||||||
|
|
||||||
|
list->last_hot = last_hot_new;
|
||||||
|
|
||||||
|
if (change == 0)
|
||||||
|
return end_marker;
|
||||||
|
|
||||||
|
return (change > 0) ? list->last_hot : last_hot_old;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
int change = target_hot_count - list->num_hot;
|
||||||
|
ocf_cache_line_t pivot;
|
||||||
|
|
||||||
|
if (!list->track_hot)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* 1 - update hot counter */
|
||||||
|
list->num_hot = target_hot_count;
|
||||||
|
|
||||||
|
/* 2 - update last hot */
|
||||||
|
pivot = balance_update_last_hot(cache, list, change);
|
||||||
|
|
||||||
|
/* 3 - change hot bit for cacheline at the end of hot list */
|
||||||
|
if (pivot != end_marker)
|
||||||
|
ocf_metadata_get_lru(cache, pivot)->hot = (change >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Adds the given collision_index to the _head_ of the LRU list */
|
/* Adds the given collision_index to the _head_ of the LRU list */
|
||||||
static void add_lru_head(ocf_cache_t cache,
|
static void add_lru_head_nobalance(ocf_cache_t cache,
|
||||||
struct ocf_lru_list *list,
|
struct ocf_lru_list *list,
|
||||||
unsigned int collision_index)
|
unsigned int collision_index)
|
||||||
|
|
||||||
{
|
{
|
||||||
struct ocf_lru_meta *node;
|
struct ocf_lru_meta *node;
|
||||||
unsigned int curr_head_index;
|
unsigned int curr_head_index;
|
||||||
@ -65,13 +124,53 @@ static void add_lru_head(ocf_cache_t cache,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void add_lru_head(ocf_cache_t cache, struct ocf_lru_list *list,
|
||||||
|
ocf_cache_line_t collision_index)
|
||||||
|
{
|
||||||
|
add_lru_head_nobalance(cache, list, collision_index);
|
||||||
|
balance_lru_list(cache, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update list global pointers and node neighbours to reflect removal */
|
||||||
|
static inline void remove_update_ptrs(ocf_cache_t cache,
|
||||||
|
struct ocf_lru_list *list, ocf_cache_line_t collision_index,
|
||||||
|
struct ocf_lru_meta *node)
|
||||||
|
{
|
||||||
|
uint32_t next_lru_node = node->next;
|
||||||
|
uint32_t prev_lru_node = node->prev;
|
||||||
|
struct ocf_lru_meta *next_node;
|
||||||
|
struct ocf_lru_meta *prev_node;
|
||||||
|
bool is_head = (node->prev == end_marker);
|
||||||
|
bool is_tail = (node->next == end_marker);
|
||||||
|
|
||||||
|
if (is_head && is_tail) {
|
||||||
|
list->head = end_marker;
|
||||||
|
list->tail = end_marker;
|
||||||
|
} else if (is_head) {
|
||||||
|
list->head = next_lru_node;
|
||||||
|
next_node = ocf_metadata_get_lru(cache, next_lru_node);
|
||||||
|
next_node->prev = end_marker;
|
||||||
|
} else if (is_tail) {
|
||||||
|
list->tail = prev_lru_node;
|
||||||
|
prev_node = ocf_metadata_get_lru(cache, prev_lru_node);
|
||||||
|
prev_node->next = end_marker;
|
||||||
|
} else {
|
||||||
|
next_node = ocf_metadata_get_lru(cache, next_lru_node);
|
||||||
|
prev_node = ocf_metadata_get_lru(cache, prev_lru_node);
|
||||||
|
prev_node->next = node->next;
|
||||||
|
next_node->prev = node->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list->last_hot == collision_index)
|
||||||
|
list->last_hot = prev_lru_node;
|
||||||
|
}
|
||||||
|
|
||||||
/* Deletes the node with the given collision_index from the lru list */
|
/* Deletes the node with the given collision_index from the lru list */
|
||||||
static void remove_lru_list(ocf_cache_t cache,
|
static void remove_lru_list_nobalance(ocf_cache_t cache,
|
||||||
struct ocf_lru_list *list,
|
struct ocf_lru_list *list,
|
||||||
unsigned int collision_index)
|
ocf_cache_line_t collision_index)
|
||||||
{
|
{
|
||||||
int is_head = 0, is_tail = 0;
|
int is_head = 0, is_tail = 0;
|
||||||
uint32_t prev_lru_node, next_lru_node;
|
|
||||||
struct ocf_lru_meta *node;
|
struct ocf_lru_meta *node;
|
||||||
|
|
||||||
ENV_BUG_ON(collision_index == end_marker);
|
ENV_BUG_ON(collision_index == end_marker);
|
||||||
@ -81,142 +180,35 @@ static void remove_lru_list(ocf_cache_t cache,
|
|||||||
is_head = (list->head == collision_index);
|
is_head = (list->head == collision_index);
|
||||||
is_tail = (list->tail == collision_index);
|
is_tail = (list->tail == collision_index);
|
||||||
|
|
||||||
|
ENV_BUG_ON(is_head == (node->prev != end_marker));
|
||||||
|
ENV_BUG_ON(is_tail == (node->next != end_marker));
|
||||||
|
|
||||||
|
remove_update_ptrs(cache, list, collision_index, node);
|
||||||
|
|
||||||
|
--list->num_nodes;
|
||||||
if (node->hot)
|
if (node->hot)
|
||||||
--list->num_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->next = end_marker;
|
||||||
node->prev = 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;
|
node->hot = false;
|
||||||
--list->num_nodes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Increase / decrease number of hot elements to achieve target count.
|
static void remove_lru_list(ocf_cache_t cache, struct ocf_lru_list *list,
|
||||||
* Asssumes that the list has hot element clustered together at the
|
ocf_cache_line_t cline)
|
||||||
* 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;
|
remove_lru_list_nobalance(cache, list, cline);
|
||||||
struct ocf_lru_meta *node;
|
balance_lru_list(cache, list);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ocf_lru_set_hot(ocf_cache_t cache, struct ocf_lru_list *list,
|
||||||
|
ocf_cache_line_t cline)
|
||||||
|
|
||||||
/*-- End of LRU functions*/
|
{
|
||||||
|
remove_lru_list_nobalance(cache, list, cline);
|
||||||
|
add_lru_head_nobalance(cache, list, cline);
|
||||||
|
balance_lru_list(cache, list);
|
||||||
|
}
|
||||||
|
|
||||||
void ocf_lru_init_cline(ocf_cache_t cache, ocf_cache_line_t cline)
|
void ocf_lru_init_cline(ocf_cache_t cache, ocf_cache_line_t cline)
|
||||||
{
|
{
|
||||||
@ -252,39 +244,18 @@ static inline struct ocf_lru_list *lru_get_cline_list(ocf_cache_t cache,
|
|||||||
!metadata_test_dirty(cache, cline));
|
!metadata_test_dirty(cache, cline));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ocf_lru_move(ocf_cache_t cache, ocf_cache_line_t cline,
|
void ocf_lru_add(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);
|
struct ocf_lru_list *list = lru_get_cline_list(cache, 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);
|
|
||||||
|
|
||||||
|
add_lru_head(cache, list, cline);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the caller must hold the metadata lock */
|
static inline void ocf_lru_move(ocf_cache_t cache, ocf_cache_line_t cline,
|
||||||
void ocf_lru_rm_cline(ocf_cache_t cache, ocf_cache_line_t cline)
|
struct ocf_lru_list *src_list, struct ocf_lru_list *dst_list)
|
||||||
{
|
{
|
||||||
struct ocf_lru_list *list, *free;
|
remove_lru_list(cache, src_list, cline);
|
||||||
uint32_t lru_list = (cline % OCF_NUM_LRU_LISTS);
|
add_lru_head(cache, dst_list, cline);
|
||||||
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,
|
static void ocf_lru_repart_locked(ocf_cache_t cache, ocf_cache_line_t cline,
|
||||||
@ -298,7 +269,10 @@ static void ocf_lru_repart_locked(ocf_cache_t cache, ocf_cache_line_t cline,
|
|||||||
src_list = ocf_lru_get_list(src_part, lru_list, clean);
|
src_list = ocf_lru_get_list(src_part, lru_list, clean);
|
||||||
dst_list = ocf_lru_get_list(dst_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);
|
ocf_lru_move(cache, cline, src_list, dst_list);
|
||||||
|
ocf_metadata_set_partition_id(cache, cline, dst_part->id);
|
||||||
|
env_atomic_dec(&src_part->runtime->curr_size);
|
||||||
|
env_atomic_inc(&dst_part->runtime->curr_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ocf_lru_repart(ocf_cache_t cache, ocf_cache_line_t cline,
|
void ocf_lru_repart(ocf_cache_t cache, ocf_cache_line_t cline,
|
||||||
@ -309,6 +283,18 @@ void ocf_lru_repart(ocf_cache_t cache, ocf_cache_line_t cline,
|
|||||||
OCF_METADATA_LRU_WR_UNLOCK(cline);
|
OCF_METADATA_LRU_WR_UNLOCK(cline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* the caller must hold the metadata lock */
|
||||||
|
void ocf_lru_rm_cline(ocf_cache_t cache, ocf_cache_line_t cline)
|
||||||
|
{
|
||||||
|
ocf_part_id_t part_id = ocf_metadata_get_partition_id(cache, cline);
|
||||||
|
struct ocf_part *part = &cache->user_parts[part_id].part;
|
||||||
|
|
||||||
|
ENV_BUG_ON(metadata_test_dirty(cache, cline));
|
||||||
|
|
||||||
|
ocf_lru_repart(cache, cline, part, &cache->free);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void lru_iter_init(struct ocf_lru_iter *iter, ocf_cache_t cache,
|
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,
|
struct ocf_part *part, uint32_t start_lru, bool clean,
|
||||||
_lru_hash_locked_pfn hash_locked, struct ocf_request *req)
|
_lru_hash_locked_pfn hash_locked, struct ocf_request *req)
|
||||||
@ -484,9 +470,7 @@ static inline ocf_cache_line_t lru_iter_eviction_next(struct ocf_lru_iter *iter,
|
|||||||
ocf_lru_repart_locked(cache, cline, part,
|
ocf_lru_repart_locked(cache, cline, part,
|
||||||
dst_part);
|
dst_part);
|
||||||
} else {
|
} else {
|
||||||
remove_lru_list(cache, list, cline);
|
ocf_lru_set_hot(cache, list, cline);
|
||||||
add_lru_head(cache, list, cline);
|
|
||||||
balance_lru_list(cache, list);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -519,6 +503,8 @@ static inline ocf_cache_line_t lru_iter_free_next(struct ocf_lru_iter *iter,
|
|||||||
struct ocf_part *free = iter->part;
|
struct ocf_part *free = iter->part;
|
||||||
struct ocf_lru_list *list;
|
struct ocf_lru_list *list;
|
||||||
|
|
||||||
|
ENV_BUG_ON(dst_part == free);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
curr_lru = _lru_next_lru(iter);
|
curr_lru = _lru_next_lru(iter);
|
||||||
|
|
||||||
@ -797,9 +783,13 @@ uint32_t ocf_lru_req_clines(struct ocf_request *req,
|
|||||||
/* the caller must hold the metadata lock */
|
/* the caller must hold the metadata lock */
|
||||||
void ocf_lru_hot_cline(ocf_cache_t cache, ocf_cache_line_t cline)
|
void ocf_lru_hot_cline(ocf_cache_t cache, ocf_cache_line_t cline)
|
||||||
{
|
{
|
||||||
|
const uint32_t lru_list = (cline % OCF_NUM_LRU_LISTS);
|
||||||
struct ocf_lru_meta *node;
|
struct ocf_lru_meta *node;
|
||||||
struct ocf_lru_list *list;
|
struct ocf_lru_list *list;
|
||||||
|
ocf_part_id_t part_id;
|
||||||
|
struct ocf_part *part;
|
||||||
bool hot;
|
bool hot;
|
||||||
|
bool clean;
|
||||||
|
|
||||||
node = ocf_metadata_get_lru(cache, cline);
|
node = ocf_metadata_get_lru(cache, cline);
|
||||||
|
|
||||||
@ -810,19 +800,18 @@ void ocf_lru_hot_cline(ocf_cache_t cache, ocf_cache_line_t cline)
|
|||||||
if (hot)
|
if (hot)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
list = lru_get_cline_list(cache, cline);
|
part_id = ocf_metadata_get_partition_id(cache, cline);
|
||||||
|
part = &cache->user_parts[part_id].part;
|
||||||
|
clean = !metadata_test_dirty(cache, cline);
|
||||||
|
list = ocf_lru_get_list(part, lru_list, clean);
|
||||||
|
|
||||||
OCF_METADATA_LRU_WR_LOCK(cline);
|
OCF_METADATA_LRU_WR_LOCK(cline);
|
||||||
|
|
||||||
if (node->next != end_marker ||
|
/* cacheline must be on the list when set_hot gets called */
|
||||||
node->prev != end_marker ||
|
ENV_BUG_ON(node->next == end_marker && list->tail != cline);
|
||||||
list->head == cline || list->tail == cline) {
|
ENV_BUG_ON(node->prev == end_marker && list->head != cline);
|
||||||
remove_lru_list(cache, list, cline);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update LRU */
|
ocf_lru_set_hot(cache, list, cline);
|
||||||
add_lru_head(cache, list, cline);
|
|
||||||
balance_lru_list(cache, list);
|
|
||||||
|
|
||||||
OCF_METADATA_LRU_WR_UNLOCK(cline);
|
OCF_METADATA_LRU_WR_UNLOCK(cline);
|
||||||
}
|
}
|
||||||
@ -870,9 +859,7 @@ void ocf_lru_clean_cline(ocf_cache_t cache, struct ocf_part *part,
|
|||||||
|
|
||||||
OCF_METADATA_LRU_WR_LOCK(cline);
|
OCF_METADATA_LRU_WR_LOCK(cline);
|
||||||
remove_lru_list(cache, dirty_list, cline);
|
remove_lru_list(cache, dirty_list, cline);
|
||||||
balance_lru_list(cache, dirty_list);
|
|
||||||
add_lru_head(cache, clean_list, cline);
|
add_lru_head(cache, clean_list, cline);
|
||||||
balance_lru_list(cache, clean_list);
|
|
||||||
OCF_METADATA_LRU_WR_UNLOCK(cline);
|
OCF_METADATA_LRU_WR_UNLOCK(cline);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -888,9 +875,7 @@ void ocf_lru_dirty_cline(ocf_cache_t cache, struct ocf_part *part,
|
|||||||
|
|
||||||
OCF_METADATA_LRU_WR_LOCK(cline);
|
OCF_METADATA_LRU_WR_LOCK(cline);
|
||||||
remove_lru_list(cache, clean_list, cline);
|
remove_lru_list(cache, clean_list, cline);
|
||||||
balance_lru_list(cache, clean_list);
|
|
||||||
add_lru_head(cache, dirty_list, cline);
|
add_lru_head(cache, dirty_list, cline);
|
||||||
balance_lru_list(cache, dirty_list);
|
|
||||||
OCF_METADATA_LRU_WR_UNLOCK(cline);
|
OCF_METADATA_LRU_WR_UNLOCK(cline);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -942,7 +927,6 @@ void ocf_lru_populate(ocf_cache_t cache, ocf_cache_line_t num_free_clines)
|
|||||||
list = ocf_lru_get_list(&cache->free, lru_list, true);
|
list = ocf_lru_get_list(&cache->free, lru_list, true);
|
||||||
|
|
||||||
add_lru_head(cache, list, cline);
|
add_lru_head(cache, list, cline);
|
||||||
balance_lru_list(cache, list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we should have reached the last invalid cache line */
|
/* we should have reached the last invalid cache line */
|
||||||
|
@ -20,6 +20,7 @@ bool ocf_lru_can_evict(struct ocf_cache *cache);
|
|||||||
uint32_t ocf_lru_req_clines(struct ocf_request *req,
|
uint32_t ocf_lru_req_clines(struct ocf_request *req,
|
||||||
struct ocf_part *src_part, uint32_t cline_no);
|
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_hot_cline(struct ocf_cache *cache, ocf_cache_line_t cline);
|
||||||
|
void ocf_lru_add(ocf_cache_t cache, ocf_cache_line_t cline);
|
||||||
void ocf_lru_init(struct ocf_cache *cache, struct ocf_part *part);
|
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,
|
void ocf_lru_dirty_cline(struct ocf_cache *cache, struct ocf_part *part,
|
||||||
ocf_cache_line_t cline);
|
ocf_cache_line_t cline);
|
||||||
|
@ -6,9 +6,13 @@
|
|||||||
* update_lru_tail
|
* update_lru_tail
|
||||||
* update_lru_head_tail
|
* update_lru_head_tail
|
||||||
* _lru_init
|
* _lru_init
|
||||||
* add_lru_head
|
* add_lru_head_nobalance
|
||||||
* remove_lru_list
|
* remove_lru_list_nobalance
|
||||||
|
* remove_update_list
|
||||||
|
* remove_update_ptrs
|
||||||
* balance_lru_list
|
* balance_lru_list
|
||||||
|
* balance_update_last_hot
|
||||||
|
* ocf_get_lru
|
||||||
* </functions_to_leave>
|
* </functions_to_leave>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -98,8 +102,8 @@ static void _lru_init_test02(void **state)
|
|||||||
|
|
||||||
for (i = 1; i <= 8; i++)
|
for (i = 1; i <= 8; i++)
|
||||||
{
|
{
|
||||||
add_lru_head(NULL, &l, i, end_marker);
|
add_lru_head_nobalance(NULL, &l, i, NULL);
|
||||||
balance_lru_list(NULL, &l, end_marker);
|
balance_lru_list(NULL, &l, NULL);
|
||||||
assert_int_equal(l.num_hot, i / 2);
|
assert_int_equal(l.num_hot, i / 2);
|
||||||
assert_int_equal(l.num_nodes, i);
|
assert_int_equal(l.num_nodes, i);
|
||||||
assert_int_equal(l.head, i);
|
assert_int_equal(l.head, i);
|
||||||
@ -122,8 +126,8 @@ static void _lru_init_test03(void **state)
|
|||||||
_lru_init(&l, true);
|
_lru_init(&l, true);
|
||||||
|
|
||||||
for (i = 1; i <= 8; i++) {
|
for (i = 1; i <= 8; i++) {
|
||||||
add_lru_head(NULL, &l, i, end_marker);
|
add_lru_head_nobalance(NULL, &l, i, NULL);
|
||||||
balance_lru_list(NULL, &l, end_marker);
|
balance_lru_list(NULL, &l, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 8; i >= 1; i--) {
|
for (i = 8; i >= 1; i--) {
|
||||||
@ -135,8 +139,8 @@ static void _lru_init_test03(void **state)
|
|||||||
i - i / 2 + 1);
|
i - i / 2 + 1);
|
||||||
check_hot_elems(&l);
|
check_hot_elems(&l);
|
||||||
|
|
||||||
remove_lru_list(NULL, &l, i, end_marker);
|
remove_lru_list_nobalance(NULL, &l, i, NULL);
|
||||||
balance_lru_list(NULL, &l, end_marker);
|
balance_lru_list(NULL, &l, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_int_equal(l.num_hot, 0);
|
assert_int_equal(l.num_hot, 0);
|
||||||
@ -158,8 +162,8 @@ static void _lru_init_test04(void **state)
|
|||||||
_lru_init(&l, true);
|
_lru_init(&l, true);
|
||||||
|
|
||||||
for (i = 1; i <= 8; i++) {
|
for (i = 1; i <= 8; i++) {
|
||||||
add_lru_head(NULL, &l, i, end_marker);
|
add_lru_head_nobalance(NULL, &l, i, NULL);
|
||||||
balance_lru_list(NULL, &l, end_marker);
|
balance_lru_list(NULL, &l, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 8; i >= 1; i--) {
|
for (i = 8; i >= 1; i--) {
|
||||||
@ -171,8 +175,8 @@ static void _lru_init_test04(void **state)
|
|||||||
8 - i / 2 + 1);
|
8 - i / 2 + 1);
|
||||||
check_hot_elems(&l);
|
check_hot_elems(&l);
|
||||||
|
|
||||||
remove_lru_list(NULL, &l, 9 - i, end_marker);
|
remove_lru_list_nobalance(NULL, &l, 9 - i, NULL);
|
||||||
balance_lru_list(NULL, &l, end_marker);
|
balance_lru_list(NULL, &l, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_int_equal(l.num_hot, 0);
|
assert_int_equal(l.num_hot, 0);
|
||||||
@ -196,8 +200,8 @@ static void _lru_init_test05(void **state)
|
|||||||
_lru_init(&l, true);
|
_lru_init(&l, true);
|
||||||
|
|
||||||
for (i = 1; i <= 8; i++) {
|
for (i = 1; i <= 8; i++) {
|
||||||
add_lru_head(NULL, &l, i, end_marker);
|
add_lru_head_nobalance(NULL, &l, i, NULL);
|
||||||
balance_lru_list(NULL, &l, end_marker);
|
balance_lru_list(NULL, &l, NULL);
|
||||||
present[i] = true;
|
present[i] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,8 +223,8 @@ static void _lru_init_test05(void **state)
|
|||||||
check_hot_elems(&l);
|
check_hot_elems(&l);
|
||||||
|
|
||||||
present[l.last_hot] = false;
|
present[l.last_hot] = false;
|
||||||
remove_lru_list(NULL, &l, l.last_hot, end_marker);
|
remove_lru_list_nobalance(NULL, &l, l.last_hot, NULL);
|
||||||
balance_lru_list(NULL, &l, end_marker);
|
balance_lru_list(NULL, &l, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_int_equal(l.num_hot, 1);
|
assert_int_equal(l.num_hot, 1);
|
||||||
@ -243,14 +247,14 @@ static void _lru_init_test06(void **state)
|
|||||||
_lru_init(&l, true);
|
_lru_init(&l, true);
|
||||||
|
|
||||||
for (i = 1; i <= 8; i++) {
|
for (i = 1; i <= 8; i++) {
|
||||||
add_lru_head(NULL, &l, i, end_marker);
|
add_lru_head_nobalance(NULL, &l, i, NULL);
|
||||||
balance_lru_list(NULL, &l, end_marker);
|
balance_lru_list(NULL, &l, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
count = 8;
|
count = 8;
|
||||||
|
|
||||||
remove_lru_list(NULL, &l, 7, end_marker);
|
remove_lru_list_nobalance(NULL, &l, 7, NULL);
|
||||||
balance_lru_list(NULL, &l, end_marker);
|
balance_lru_list(NULL, &l, NULL);
|
||||||
--count;
|
--count;
|
||||||
assert_int_equal(l.num_hot, count / 2);
|
assert_int_equal(l.num_hot, count / 2);
|
||||||
assert_int_equal(l.num_nodes, count);
|
assert_int_equal(l.num_nodes, count);
|
||||||
@ -258,8 +262,8 @@ static void _lru_init_test06(void **state)
|
|||||||
assert_int_equal(l.tail, 1);
|
assert_int_equal(l.tail, 1);
|
||||||
assert_int_equal(l.last_hot, 5);
|
assert_int_equal(l.last_hot, 5);
|
||||||
|
|
||||||
remove_lru_list(NULL, &l, 6, end_marker);
|
remove_lru_list_nobalance(NULL, &l, 6, NULL);
|
||||||
balance_lru_list(NULL, &l, end_marker);
|
balance_lru_list(NULL, &l, NULL);
|
||||||
--count;
|
--count;
|
||||||
assert_int_equal(l.num_hot, count / 2);
|
assert_int_equal(l.num_hot, count / 2);
|
||||||
assert_int_equal(l.num_nodes, count);
|
assert_int_equal(l.num_nodes, count);
|
||||||
@ -267,8 +271,8 @@ static void _lru_init_test06(void **state)
|
|||||||
assert_int_equal(l.tail, 1);
|
assert_int_equal(l.tail, 1);
|
||||||
assert_int_equal(l.last_hot, 4);
|
assert_int_equal(l.last_hot, 4);
|
||||||
|
|
||||||
remove_lru_list(NULL, &l, 5, end_marker);
|
remove_lru_list_nobalance(NULL, &l, 5, NULL);
|
||||||
balance_lru_list(NULL, &l, end_marker);
|
balance_lru_list(NULL, &l, NULL);
|
||||||
--count;
|
--count;
|
||||||
assert_int_equal(l.num_hot, count / 2);
|
assert_int_equal(l.num_hot, count / 2);
|
||||||
assert_int_equal(l.num_nodes, count);
|
assert_int_equal(l.num_nodes, count);
|
||||||
@ -276,8 +280,8 @@ static void _lru_init_test06(void **state)
|
|||||||
assert_int_equal(l.tail, 1);
|
assert_int_equal(l.tail, 1);
|
||||||
assert_int_equal(l.last_hot, 4);
|
assert_int_equal(l.last_hot, 4);
|
||||||
|
|
||||||
remove_lru_list(NULL, &l, 4, end_marker);
|
remove_lru_list_nobalance(NULL, &l, 4, NULL);
|
||||||
balance_lru_list(NULL, &l, end_marker);
|
balance_lru_list(NULL, &l, NULL);
|
||||||
--count;
|
--count;
|
||||||
assert_int_equal(l.num_hot, count / 2);
|
assert_int_equal(l.num_hot, count / 2);
|
||||||
assert_int_equal(l.num_nodes, count);
|
assert_int_equal(l.num_nodes, count);
|
||||||
@ -285,8 +289,8 @@ static void _lru_init_test06(void **state)
|
|||||||
assert_int_equal(l.tail, 1);
|
assert_int_equal(l.tail, 1);
|
||||||
assert_int_equal(l.last_hot, 3);
|
assert_int_equal(l.last_hot, 3);
|
||||||
|
|
||||||
remove_lru_list(NULL, &l, 3, end_marker);
|
remove_lru_list_nobalance(NULL, &l, 3, NULL);
|
||||||
balance_lru_list(NULL, &l, end_marker);
|
balance_lru_list(NULL, &l, NULL);
|
||||||
--count;
|
--count;
|
||||||
assert_int_equal(l.num_hot, count / 2);
|
assert_int_equal(l.num_hot, count / 2);
|
||||||
assert_int_equal(l.num_nodes, count);
|
assert_int_equal(l.num_nodes, count);
|
||||||
@ -294,8 +298,8 @@ static void _lru_init_test06(void **state)
|
|||||||
assert_int_equal(l.tail, 1);
|
assert_int_equal(l.tail, 1);
|
||||||
assert_int_equal(l.last_hot, 8);
|
assert_int_equal(l.last_hot, 8);
|
||||||
|
|
||||||
remove_lru_list(NULL, &l, 8, end_marker);
|
remove_lru_list_nobalance(NULL, &l, 8, NULL);
|
||||||
balance_lru_list(NULL, &l, end_marker);
|
balance_lru_list(NULL, &l, NULL);
|
||||||
--count;
|
--count;
|
||||||
assert_int_equal(l.num_hot, count / 2);
|
assert_int_equal(l.num_hot, count / 2);
|
||||||
assert_int_equal(l.num_nodes, count);
|
assert_int_equal(l.num_nodes, count);
|
||||||
@ -303,8 +307,8 @@ static void _lru_init_test06(void **state)
|
|||||||
assert_int_equal(l.tail, 1);
|
assert_int_equal(l.tail, 1);
|
||||||
assert_int_equal(l.last_hot, 2);
|
assert_int_equal(l.last_hot, 2);
|
||||||
|
|
||||||
remove_lru_list(NULL, &l, 2, end_marker);
|
remove_lru_list_nobalance(NULL, &l, 2, NULL);
|
||||||
balance_lru_list(NULL, &l, end_marker);
|
balance_lru_list(NULL, &l, NULL);
|
||||||
--count;
|
--count;
|
||||||
assert_int_equal(l.num_hot, count / 2);
|
assert_int_equal(l.num_hot, count / 2);
|
||||||
assert_int_equal(l.num_nodes, count);
|
assert_int_equal(l.num_nodes, count);
|
||||||
|
@ -5,11 +5,13 @@
|
|||||||
* INSERT HERE LIST OF FUNCTIONS YOU WANT TO LEAVE
|
* INSERT HERE LIST OF FUNCTIONS YOU WANT TO LEAVE
|
||||||
* ONE FUNCTION PER LINE
|
* ONE FUNCTION PER LINE
|
||||||
* lru_iter_init
|
* lru_iter_init
|
||||||
|
* lru_iter_cleaning_init
|
||||||
* _lru_next_lru
|
* _lru_next_lru
|
||||||
* _lru_lru_is_empty
|
* _lru_lru_is_empty
|
||||||
* _lru_lru_set_empty
|
* _lru_lru_set_empty
|
||||||
* _lru_lru_all_empty
|
* _lru_lru_all_empty
|
||||||
* ocf_rotate_right
|
* ocf_rotate_right
|
||||||
|
* ocf_get_lru
|
||||||
* lru_iter_eviction_next
|
* lru_iter_eviction_next
|
||||||
* lru_iter_cleaning_next
|
* lru_iter_cleaning_next
|
||||||
* </functions_to_leave>
|
* </functions_to_leave>
|
||||||
@ -37,7 +39,7 @@
|
|||||||
|
|
||||||
#include "ocf_lru.c/lru_iter_generated_wraps.c"
|
#include "ocf_lru.c/lru_iter_generated_wraps.c"
|
||||||
|
|
||||||
//#define DEBUG
|
// #define DEBUG
|
||||||
|
|
||||||
struct ocf_cache_line_concurrency *__wrap_ocf_cache_line_concurrency(ocf_cache_t cache)
|
struct ocf_cache_line_concurrency *__wrap_ocf_cache_line_concurrency(ocf_cache_t cache)
|
||||||
{
|
{
|
||||||
@ -222,7 +224,7 @@ struct ocf_lru_list *__wrap_ocf_lru_get_list(struct ocf_user_part *user_part,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
print_message("list for case %u lru %u: head: %u tail %u elems %u\n",
|
print_message("list for case %u lru %u: head: 0x%x tail 0x%x elems 0x%x\n",
|
||||||
current_case, lru, list.head, list.tail, list.num_nodes);
|
current_case, lru, list.head, list.tail, list.num_nodes);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -258,7 +260,7 @@ struct ocf_lru_meta *__wrap_ocf_metadata_get_lru(
|
|||||||
|
|
||||||
g_lru_meta.next = test_cases[j + 1][i][current_case];
|
g_lru_meta.next = test_cases[j + 1][i][current_case];
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
print_message("[%u] next %u prev %u\n",
|
print_message("[%u] next 0x%x prev 0x%x\n",
|
||||||
line, g_lru_meta.next,
|
line, g_lru_meta.next,
|
||||||
g_lru_meta.prev);
|
g_lru_meta.prev);
|
||||||
#endif
|
#endif
|
||||||
@ -372,8 +374,7 @@ static void _lru_run_test(unsigned test_case)
|
|||||||
pos[i]++;
|
pos[i]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
lru_iter_init(&iter, NULL, NULL, start_pos, false, false, false,
|
lru_iter_cleaning_init(&iter, NULL, NULL, start_pos);
|
||||||
NULL, NULL);
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
/* check what is expected to be returned from iterator */
|
/* check what is expected to be returned from iterator */
|
||||||
@ -402,6 +403,15 @@ static void _lru_run_test(unsigned test_case)
|
|||||||
/* get cacheline from iterator */
|
/* get cacheline from iterator */
|
||||||
cache_line = lru_iter_cleaning_next(&iter);
|
cache_line = lru_iter_cleaning_next(&iter);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (cache_line == expected_cache_line) {
|
||||||
|
print_message("case %u cline 0x%x ok\n",
|
||||||
|
test_case, cache_line);
|
||||||
|
} else {
|
||||||
|
print_message("case %u cline 0x%x NOK expected 0x%x\n",
|
||||||
|
test_case, cache_line, expected_cache_line);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
assert_int_equal(cache_line, expected_cache_line);
|
assert_int_equal(cache_line, expected_cache_line);
|
||||||
|
|
||||||
curr_lru = (curr_lru + 1) % OCF_NUM_LRU_LISTS;
|
curr_lru = (curr_lru + 1) % OCF_NUM_LRU_LISTS;
|
||||||
|
Loading…
Reference in New Issue
Block a user