Remove partition list
Signed-off-by: Adam Rutkowski <adam.j.rutkowski@intel.com>
This commit is contained in:
@@ -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"
|
||||
@@ -94,7 +93,7 @@ static ocf_cache_line_t ocf_metadata_get_entries(
|
||||
return OCF_USER_IO_CLASS_MAX + 1;
|
||||
|
||||
case metadata_segment_part_runtime:
|
||||
return OCF_USER_IO_CLASS_MAX + 1;
|
||||
return OCF_NUM_PARTITIONS;
|
||||
|
||||
case metadata_segment_core_config:
|
||||
return OCF_CORE_MAX;
|
||||
@@ -580,6 +579,8 @@ static int ocf_metadata_init_fixed_size(struct ocf_cache *cache,
|
||||
&part_runtime_meta[i].runtime;
|
||||
cache->user_parts[i].part.id = i;
|
||||
}
|
||||
cache->free.runtime= &part_runtime_meta[PARTITION_FREELIST].runtime;
|
||||
cache->free.id = PARTITION_FREELIST;
|
||||
|
||||
/* Set core metadata */
|
||||
core_meta_config = METADATA_MEM_POOL(ctrl,
|
||||
@@ -1154,10 +1155,13 @@ 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,
|
||||
|
@@ -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));
|
||||
|
@@ -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].part.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);
|
||||
}
|
||||
|
@@ -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__ */
|
||||
|
@@ -8,9 +8,8 @@
|
||||
#include "metadata_internal.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,178 +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_part *part = &cache->user_parts[part_id].part;
|
||||
|
||||
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 *user_part = &cache->user_parts[part_id];
|
||||
struct ocf_part *part = &user_part->part;
|
||||
|
||||
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_user_part_is_valid(user_part)) {
|
||||
/* Partition becomes empty, and is not valid
|
||||
* update list of partitions
|
||||
*/
|
||||
ocf_user_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 *user_part = &cache->user_parts[part_id];
|
||||
struct ocf_part *part = &user_part->part;
|
||||
|
||||
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_user_part_is_valid(user_part)) {
|
||||
/* Partition becomes not empty, and is not valid
|
||||
* update list of partitions
|
||||
*/
|
||||
ocf_user_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);
|
||||
}
|
||||
|
@@ -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__ */
|
||||
|
@@ -10,6 +10,8 @@
|
||||
#include "../cleaning/cleaning.h"
|
||||
#include "../eviction/eviction.h"
|
||||
|
||||
#define OCF_NUM_PARTITIONS OCF_USER_IO_CLASS_MAX + 2
|
||||
|
||||
struct ocf_user_part_config {
|
||||
char name[OCF_IO_CLASS_NAME_MAX];
|
||||
uint32_t min_size;
|
||||
@@ -27,8 +29,7 @@ struct ocf_user_part_config {
|
||||
};
|
||||
|
||||
struct ocf_part_runtime {
|
||||
uint32_t curr_size;
|
||||
uint32_t head;
|
||||
env_atomic curr_size;
|
||||
struct eviction_policy eviction[OCF_NUM_EVICTION_LISTS];
|
||||
};
|
||||
|
||||
@@ -43,6 +44,8 @@ struct ocf_lru_iter
|
||||
ocf_cache_line_t curr_cline[OCF_NUM_EVICTION_LISTS];
|
||||
/* cache object */
|
||||
ocf_cache_t cache;
|
||||
/* cacheline concurrency */
|
||||
struct ocf_alock *c;
|
||||
/* target partition */
|
||||
struct ocf_part *part;
|
||||
/* available (non-empty) eviction list bitmap rotated so that current
|
||||
@@ -59,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
|
||||
|
Reference in New Issue
Block a user