From 4961eee3a1fef1d3ffb4f2a04dd3d666fd4a6123 Mon Sep 17 00:00:00 2001 From: Daniel Madej Date: Wed, 16 Apr 2025 08:56:17 +0200 Subject: [PATCH 1/3] Moved partition_id to ocf_lru_meta Signed-off-by: Daniel Madej --- src/metadata/metadata.c | 4 ++-- src/metadata/metadata_collision.h | 3 +-- src/metadata/metadata_partition.c | 9 +++++---- src/ocf_lru.c | 4 +--- src/ocf_lru_structs.h | 2 ++ 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/metadata/metadata.c b/src/metadata/metadata.c index a40695191..566bbeb9a 100644 --- a/src/metadata/metadata.c +++ b/src/metadata/metadata.c @@ -1498,7 +1498,7 @@ 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; @@ -1506,7 +1506,7 @@ void ocf_metadata_get_core_and_part_id(struct ocf_cache *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); diff --git a/src/metadata/metadata_collision.h b/src/metadata/metadata_collision.h index 9a76ad153..3857eb800 100644 --- a/src/metadata/metadata_collision.h +++ b/src/metadata/metadata_collision.h @@ -1,5 +1,6 @@ /* * Copyright(c) 2012-2022 Intel Corporation + * Copyright(c) 2025 Huawei Technologies * SPDX-License-Identifier: BSD-3-Clause */ @@ -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)); /** diff --git a/src/metadata/metadata_partition.c b/src/metadata/metadata_partition.c index 6754a487b..6186acd19 100644 --- a/src/metadata/metadata_partition.c +++ b/src/metadata/metadata_partition.c @@ -1,5 +1,6 @@ /* * Copyright(c) 2012-2021 Intel Corporation + * Copyright(c) 2025 Huawei Technologies * SPDX-License-Identifier: BSD-3-Clause */ @@ -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); @@ -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; diff --git a/src/ocf_lru.c b/src/ocf_lru.c index a0ba95cf4..02f93501c 100644 --- a/src/ocf_lru.c +++ b/src/ocf_lru.c @@ -767,7 +767,6 @@ 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; @@ -781,8 +780,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; clean = !metadata_test_dirty(cache, cline); list = ocf_lru_get_list(part, lru_list, clean); diff --git a/src/ocf_lru_structs.h b/src/ocf_lru_structs.h index c5bfc1b6b..22dec2db7 100644 --- a/src/ocf_lru_structs.h +++ b/src/ocf_lru_structs.h @@ -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__ @@ -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 { From 2a4cbb79a028bd65454caf9951a8cfbf651ee3cf Mon Sep 17 00:00:00 2001 From: Daniel Madej Date: Tue, 22 Apr 2025 08:26:17 +0200 Subject: [PATCH 2/3] Repart cache lines to default IO class Signed-off-by: Daniel Madej --- inc/ocf_mngt.h | 14 +++++- src/mngt/ocf_mngt_io_class.c | 28 +++++++++++ src/ocf_lru.c | 95 +++++++++++++++++++++++++++++++++++- src/ocf_lru.h | 3 ++ 4 files changed, 137 insertions(+), 3 deletions(-) diff --git a/inc/ocf_mngt.h b/inc/ocf_mngt.h index 0109ff86c..ff478afc0 100644 --- a/inc/ocf_mngt.h +++ b/inc/ocf_mngt.h @@ -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 */ @@ -1024,6 +1024,18 @@ 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 from all IO classes to default + * + * @param[in] cache Handle for cache + * @param[in] cfg IO class configuration + * + * @retval 0 Repartitioning successful + * @retval Non-zero Error occurred + */ +int ocf_repart_all_to_default(ocf_cache_t cache, + const struct ocf_mngt_io_classes_config *cfg); + /** * @brief Asociate new UUID value with given core * diff --git a/src/mngt/ocf_mngt_io_class.c b/src/mngt/ocf_mngt_io_class.c index b9241c63d..37dea6e25 100644 --- a/src/mngt/ocf_mngt_io_class.c +++ b/src/mngt/ocf_mngt_io_class.c @@ -1,5 +1,6 @@ /* * Copyright(c) 2012-2021 Intel Corporation + * Copyright(c) 2025 Huawei Technologies * SPDX-License-Identifier: BSD-3-Clause */ @@ -328,3 +329,30 @@ int ocf_mngt_cache_io_classes_configure(ocf_cache_t cache, return result; } + +int ocf_repart_all_to_default(ocf_cache_t cache, + const struct ocf_mngt_io_classes_config *cfg) +{ + 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++) { + 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; +} diff --git a/src/ocf_lru.c b/src/ocf_lru.c index 02f93501c..3725b1cc6 100644 --- a/src/ocf_lru.c +++ b/src/ocf_lru.c @@ -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) @@ -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) { @@ -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)) { @@ -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( + 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); + + 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) { @@ -761,6 +828,30 @@ 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) { diff --git a/src/ocf_lru.h b/src/ocf_lru.h index 79fc55990..4a0ecd116 100644 --- a/src/ocf_lru.h +++ b/src/ocf_lru.h @@ -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__ @@ -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, From 86c6bbc9390b77780d64c6f7efa06a1a4da0c02c Mon Sep 17 00:00:00 2001 From: Daniel Madej Date: Tue, 22 Apr 2025 08:26:17 +0200 Subject: [PATCH 3/3] Optional repartitioning when reconfiguring IO classes With `all` parameter set repartition data from all IO classes. If `all` is unset repartition only from deleted IO classes. Signed-off-by: Daniel Madej --- inc/ocf_mngt.h | 7 ++++--- src/mngt/ocf_mngt_io_class.c | 12 +++++++----- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/inc/ocf_mngt.h b/inc/ocf_mngt.h index ff478afc0..92c9554b7 100644 --- a/inc/ocf_mngt.h +++ b/inc/ocf_mngt.h @@ -1025,16 +1025,17 @@ int ocf_mngt_cache_io_classes_configure(ocf_cache_t cache, const struct ocf_mngt_io_classes_config *cfg); /** - * @brief Repartition lines from all IO classes to default + * @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_all_to_default(ocf_cache_t cache, - const struct ocf_mngt_io_classes_config *cfg); +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 diff --git a/src/mngt/ocf_mngt_io_class.c b/src/mngt/ocf_mngt_io_class.c index 37dea6e25..c1fa4d189 100644 --- a/src/mngt/ocf_mngt_io_class.c +++ b/src/mngt/ocf_mngt_io_class.c @@ -330,8 +330,8 @@ int ocf_mngt_cache_io_classes_configure(ocf_cache_t cache, return result; } -int ocf_repart_all_to_default(ocf_cache_t cache, - const struct ocf_mngt_io_classes_config *cfg) +int ocf_repart_to_default(ocf_cache_t cache, + const struct ocf_mngt_io_classes_config *cfg, bool all) { int i; @@ -342,9 +342,11 @@ int ocf_repart_all_to_default(ocf_cache_t cache, _ocf_mngt_set_partition_size(cache, i, 0, 0); for (i = 1; i < OCF_USER_IO_CLASS_MAX; i++) { - ocf_lru_repart_all(cache, - &cache->user_parts[i].part, - &cache->user_parts[0].part); + if (all || !cfg->config[i].name) { + ocf_lru_repart_all(cache, + &cache->user_parts[i].part, + &cache->user_parts[0].part); + } } /* Reenable IO classes */