Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion inc/ocf_mngt.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright(c) 2012-2022 Intel Corporation
* Copyright(c) 2024 Huawei Technologies
* Copyright(c) 2024-2025 Huawei Technologies
* SPDX-License-Identifier: BSD-3-Clause
*/

Expand Down Expand Up @@ -1024,6 +1024,19 @@ struct ocf_mngt_io_classes_config {
int ocf_mngt_cache_io_classes_configure(ocf_cache_t cache,
const struct ocf_mngt_io_classes_config *cfg);

/**
* @brief Repartition lines to default IO class
*
* @param[in] cache Handle for cache
* @param[in] cfg IO class configuration
* @param[in] all Repartition from all IO classes (including reconfigured)
*
* @retval 0 Repartitioning successful
* @retval Non-zero Error occurred
*/
int ocf_repart_to_default(ocf_cache_t cache,
const struct ocf_mngt_io_classes_config *cfg, bool all);

/**
* @brief Asociate new UUID value with given core
*
Expand Down
4 changes: 2 additions & 2 deletions src/metadata/metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -1498,15 +1498,15 @@ void ocf_metadata_get_core_and_part_id(struct ocf_cache *cache,
ocf_part_id_t *part_id)
{
const struct ocf_metadata_map *collision;
const struct ocf_metadata_list_info *info;
const struct ocf_lru_meta *info;
struct ocf_metadata_ctrl *ctrl =
(struct ocf_metadata_ctrl *) cache->metadata.priv;

collision = ocf_metadata_raw_rd_access(cache,
&(ctrl->raw_desc[metadata_segment_collision]), line);

info = ocf_metadata_raw_rd_access(cache,
&(ctrl->raw_desc[metadata_segment_list_info]), line);
&(ctrl->raw_desc[metadata_segment_lru]), line);

ENV_BUG_ON(!collision || !info);

Expand Down
3 changes: 1 addition & 2 deletions src/metadata/metadata_collision.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright(c) 2012-2022 Intel Corporation
* Copyright(c) 2025 Huawei Technologies
* SPDX-License-Identifier: BSD-3-Clause
*/

Expand All @@ -15,8 +16,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_part_id_t partition_id : 8;
/*!< ID of partition where is assigned this cache line*/
} __attribute__((packed));

/**
Expand Down
9 changes: 5 additions & 4 deletions src/metadata/metadata_partition.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright(c) 2012-2021 Intel Corporation
* Copyright(c) 2025 Huawei Technologies
* SPDX-License-Identifier: BSD-3-Clause
*/

Expand All @@ -11,12 +12,12 @@
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;
const struct ocf_lru_meta *info;
struct ocf_metadata_ctrl *ctrl =
(struct ocf_metadata_ctrl *) cache->metadata.priv;

info = ocf_metadata_raw_rd_access(cache,
&(ctrl->raw_desc[metadata_segment_list_info]), line);
&(ctrl->raw_desc[metadata_segment_lru]), line);

ENV_BUG_ON(!info);

Expand All @@ -26,12 +27,12 @@ ocf_part_id_t ocf_metadata_get_partition_id(struct ocf_cache *cache,
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_lru_meta *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);
&(ctrl->raw_desc[metadata_segment_lru]), line);

if (info)
info->partition_id = part_id;
Expand Down
30 changes: 30 additions & 0 deletions src/mngt/ocf_mngt_io_class.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright(c) 2012-2021 Intel Corporation
* Copyright(c) 2025 Huawei Technologies
* SPDX-License-Identifier: BSD-3-Clause
*/

Expand Down Expand Up @@ -328,3 +329,32 @@ int ocf_mngt_cache_io_classes_configure(ocf_cache_t cache,

return result;
}

int ocf_repart_to_default(ocf_cache_t cache,
const struct ocf_mngt_io_classes_config *cfg, bool all)
{
int i;

/* Temporarily disable IO classes (except for default) for
* repartitioning.
*/
for (i = 1; i < OCF_USER_IO_CLASS_MAX; i++)
_ocf_mngt_set_partition_size(cache, i, 0, 0);

for (i = 1; i < OCF_USER_IO_CLASS_MAX; i++) {
if (all || !cfg->config[i].name) {
ocf_lru_repart_all(cache,
&cache->user_parts[i].part,
&cache->user_parts[0].part);
}
}

/* Reenable IO classes */
for (i = 1; i < OCF_USER_IO_CLASS_MAX; i++) {
/* Sizes already validated. */
_ocf_mngt_set_partition_size(cache, i, 0,
cfg->config[i].max_size);
}

return 0;
}
99 changes: 94 additions & 5 deletions src/ocf_lru.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,6 @@ void ocf_lru_rm_cline(ocf_cache_t cache, ocf_cache_line_t cline)
ocf_lru_repart(cache, cline, part, &cache->free);
}


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)
Expand Down Expand Up @@ -347,6 +346,11 @@ static inline void lru_iter_eviction_init(struct ocf_lru_iter *iter,
req);
}

static inline void lru_iter_repart_init(struct ocf_lru_iter *iter,
ocf_cache_t cache, struct ocf_part *part, bool clean)
{
lru_iter_init(iter, cache, part, 0, clean, NULL, NULL);
}

static inline uint32_t _lru_next_lru(struct ocf_lru_iter *iter)
{
Expand Down Expand Up @@ -558,7 +562,7 @@ static inline ocf_cache_line_t lru_iter_cleaning_next(struct ocf_lru_iter *iter)
}
if (cline != end_marker) {
iter->curr_cline[curr_lru] =
ocf_metadata_get_lru(iter->cache , cline)->prev;
ocf_metadata_get_lru(iter->cache, cline)->prev;
}

if (cline == end_marker && !_lru_lru_is_empty(iter)) {
Expand Down Expand Up @@ -588,6 +592,69 @@ static void ocf_lru_clean_end(void *private_data, int error)
env_refcnt_dec(&ctx->counter);
}

static inline ocf_cache_line_t lru_iter_repart_next(struct ocf_lru_iter *iter,
struct ocf_part *dst_part)
{
ocf_cache_t cache = iter->cache;
struct ocf_part *part = iter->part;
uint32_t curr_lru;
ocf_cache_line_t cline;
struct ocf_lru_list *list;
ocf_core_id_t core_id;
ocf_core_t core;

if (dst_part == part)
return end_marker;

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 && !ocf_cache_line_try_lock_wr(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This functions won't repart all cache lines because of this try_lock(). It will only repart the cache lines that is was able to lock. Any CL that would be locked by a concurrent IO request won't be reparted

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assumed that if there is only the default IO class active then those cache lines which can't be locked would be reparted as a result of this concurrent IO.

iter->c, cline)) {
cline = ocf_metadata_get_lru(cache, cline)->prev;
}

if (cline != end_marker) {
core_id = ocf_metadata_get_core_id(cache, cline);
core = ocf_cache_get_core(cache, core_id);
if (metadata_test_dirty(cache, cline))
ocf_cleaning_purge_cache_block(cache, cline);

ocf_lru_repart_locked(cache, cline, part, dst_part);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think ocf_lru_repart_locked() is a good fit for repartition during a managment operation because every reparted cache line will be marked as hot and will trigger unnecessary rebalancing on the default ioclass.


if (metadata_test_dirty(cache, cline)) {
/* Add cline back to cleaning policy */
ocf_cleaning_set_hot_cache_line(cache, cline);
env_atomic_inc(&core->runtime_meta
->part_counters[dst_part->id]
.dirty_clines);
env_atomic_dec(&core->runtime_meta
->part_counters[part->id].dirty_clines);
}
env_atomic_inc(&core->runtime_meta
->part_counters[dst_part->id].cached_clines);
env_atomic_dec(&core->runtime_meta
->part_counters[part->id].cached_clines);
ocf_cache_line_unlock_wr(iter->c, cline);
}

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

void ocf_lru_clean(ocf_cache_t cache, struct ocf_user_part *user_part,
ocf_queue_t io_queue, uint32_t count)
{
Expand Down Expand Up @@ -761,13 +828,36 @@ uint32_t ocf_lru_req_clines(struct ocf_request *req,
return i;
}

void ocf_lru_repart_all(ocf_cache_t cache, struct ocf_part *src_part,
struct ocf_part *dst_part)
{
struct ocf_lru_iter iter;
ocf_cache_line_t cline;

ENV_BUG_ON(src_part->id >= OCF_USER_IO_CLASS_MAX ||
dst_part->id >= OCF_USER_IO_CLASS_MAX);
if (src_part->id == dst_part->id)
return;

/* Repartition clean cache lines */
lru_iter_repart_init(&iter, cache, src_part, true);
do {
cline = lru_iter_repart_next(&iter, dst_part);
} while (cline != end_marker);

/* Repartition dirty cache lines */
lru_iter_repart_init(&iter, cache, src_part, false);
do {
cline = lru_iter_repart_next(&iter, dst_part);
} while (cline != end_marker);
}

/* the caller must hold the metadata lock */
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_list *list;
ocf_part_id_t part_id;
struct ocf_part *part;
bool hot;
bool clean;
Expand All @@ -781,8 +871,7 @@ void ocf_lru_hot_cline(ocf_cache_t cache, ocf_cache_line_t cline)
if (hot)
return;

part_id = ocf_metadata_get_partition_id(cache, cline);
part = &cache->user_parts[part_id].part;
part = &cache->user_parts[node->partition_id].part;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this change belongs to the previous commit :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed :)

clean = !metadata_test_dirty(cache, cline);
list = ocf_lru_get_list(part, lru_list, clean);

Expand Down
3 changes: 3 additions & 0 deletions src/ocf_lru.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright(c) 2012-2021 Intel Corporation
* Copyright(c) 2025 Huawei Technologies
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __EVICTION_LRU_H__
Expand Down Expand Up @@ -30,6 +31,8 @@ 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);
void ocf_lru_repart_all(ocf_cache_t cache, struct ocf_part *src_part,
struct ocf_part *dst_part);
void ocf_lru_add_free(ocf_cache_t cache, ocf_cache_line_t cline);
uint32_t ocf_lru_num_free(ocf_cache_t cache);
struct ocf_lru_list *ocf_lru_get_list(struct ocf_part *part,
Expand Down
2 changes: 2 additions & 0 deletions src/ocf_lru_structs.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright(c) 2012-2021 Intel Corporation
* Copyright(c) 2025 Huawei Technologies
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __EVICTION_LRU_STRUCTS_H__
Expand All @@ -10,6 +11,7 @@ struct ocf_lru_meta {
uint32_t prev;
uint32_t next;
uint8_t hot;
ocf_part_id_t partition_id : 8;
} __attribute__((packed));

struct ocf_lru_list {
Expand Down