From 9e6014707c117289a0e78599e1a2e97d62855167 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Sun, 4 Oct 2026 11:38:18 +0200 Subject: [PATCH 1/8] core: Move OCF_CORE_USER_DATA_SIZE to a public header Per-core user data is exposed in public API, so this constant also belongs to inc/. Signed-off-by: Robert Baldyga --- inc/ocf_def.h | 4 ++++ src/ocf_core_priv.h | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/inc/ocf_def.h b/inc/ocf_def.h index 8a354752..fa0fbf11 100644 --- a/inc/ocf_def.h +++ b/inc/ocf_def.h @@ -129,6 +129,10 @@ _Static_assert(OCF_MAX_T(uint32_t, OCF_CORE_ID_BITS) > OCF_CORE_NUM, * Size of core name */ #define OCF_CORE_NAME_SIZE 32 +/** + * Size of persistent core user metadata + */ +#define OCF_CORE_USER_DATA_SIZE 64 /** * Minimum value of valid core sequence number */ diff --git a/src/ocf_core_priv.h b/src/ocf_core_priv.h index 8bb04a2e..e21746f5 100644 --- a/src/ocf_core_priv.h +++ b/src/ocf_core_priv.h @@ -27,8 +27,6 @@ struct ocf_metadata_uuid { uint8_t data[OCF_VOLUME_UUID_MAX_SIZE]; } __packed; -#define OCF_CORE_USER_DATA_SIZE 64 - struct ocf_core_meta_config { char name[OCF_CORE_NAME_SIZE]; From dd11b9e60dd2b27cd3ba0a0fc3ec5c20018868fd Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Sun, 4 Oct 2026 10:39:54 +0200 Subject: [PATCH 2/8] metadata: Isolate partition and lru metadata structures Move all the dependencies of part_config, part_runtime and lru segments to src/metadata/. Signed-off-by: Robert Baldyga --- src/cleaning/alru_structs.h | 7 +---- src/cleaning/cleaning.h | 9 ++---- src/cleaning/nop_structs.h | 4 +-- src/metadata/metadata.c | 22 +++++--------- src/metadata/metadata.h | 2 +- src/metadata/metadata_cleaning_policy.h | 24 +++++++++++++++ src/metadata/metadata_eviction_policy.c | 3 +- src/metadata/metadata_eviction_policy.h | 13 --------- .../metadata_lru.h} | 14 ++++++--- src/metadata/metadata_partition.h | 29 ++++++++++++++++++- src/ocf_lru.h | 4 ++- src/ocf_part.h | 25 +--------------- src/ocf_space.h | 3 +- 13 files changed, 81 insertions(+), 78 deletions(-) delete mode 100644 src/metadata/metadata_eviction_policy.h rename src/{ocf_lru_structs.h => metadata/metadata_lru.h} (74%) diff --git a/src/cleaning/alru_structs.h b/src/cleaning/alru_structs.h index 78f06dfe..b8a810ba 100644 --- a/src/cleaning/alru_structs.h +++ b/src/cleaning/alru_structs.h @@ -2,6 +2,7 @@ * Copyright(c) 2012-2021 Intel Corporation * Copyright(c) 2022 David Lee * Copyright(c) 2025 Huawei Technologies + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __CLEANING_ALRU_STRUCTS_H__ @@ -26,11 +27,5 @@ struct alru_cleaning_policy_config { uint32_t dirty_ratio_inertia; /* bytes */ }; -struct alru_cleaning_policy { - env_atomic size; - uint32_t lru_head; - uint32_t lru_tail; -}; - #endif diff --git a/src/cleaning/cleaning.h b/src/cleaning/cleaning.h index 1e56af27..fcb3b719 100644 --- a/src/cleaning/cleaning.h +++ b/src/cleaning/cleaning.h @@ -1,6 +1,7 @@ /* * Copyright(c) 2012-2022 Intel Corporation * Copyright(c) 2023-2025 Huawei Technologies Co., Ltd. + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,6 +11,7 @@ #include "alru_structs.h" #include "nop_structs.h" #include "acp_structs.h" +#include "../metadata/metadata_cleaning_policy.h" #include "ocf_env_refcnt.h" #include "ocf/ocf_cleaner.h" @@ -24,13 +26,6 @@ struct cleaning_policy_config { uint8_t data[CLEANING_POLICY_CONFIG_BYTES]; } __attribute__((aligned(4))); -struct cleaning_policy { - union { - struct nop_cleaning_policy nop; - struct alru_cleaning_policy alru; - } policy; -}; - /* Cleaning policy metadata per cache line */ struct cleaning_policy_meta { union { diff --git a/src/cleaning/nop_structs.h b/src/cleaning/nop_structs.h index 636ba666..5f30d00c 100644 --- a/src/cleaning/nop_structs.h +++ b/src/cleaning/nop_structs.h @@ -1,5 +1,6 @@ /* * Copyright(c) 2012-2021 Intel Corporation + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __LAYER_CLEANING_POLICY_NOP_STRUCTS_H__ @@ -9,7 +10,4 @@ struct nop_cleaning_policy_meta { } __attribute__((packed)); -struct nop_cleaning_policy { -}; - #endif diff --git a/src/metadata/metadata.c b/src/metadata/metadata.c index 60865a5c..cfe73890 100644 --- a/src/metadata/metadata.c +++ b/src/metadata/metadata.c @@ -38,11 +38,6 @@ #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, @@ -181,7 +176,7 @@ static int64_t ocf_metadata_get_element_size( break; case metadata_segment_part_runtime: - size = sizeof(struct ocf_part_runtime_meta); + size = sizeof(struct ocf_part_runtime); break; case metadata_segment_hash: @@ -565,7 +560,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_part_runtime_meta *part_runtime_meta; + struct ocf_part_runtime *part_runtime; struct ocf_metadata_segment *superblock; ocf_core_t core; ocf_core_id_t core_id; @@ -615,18 +610,15 @@ 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_meta = METADATA_MEM_POOL(ctrl, - metadata_segment_part_runtime); + part_runtime = METADATA_MEM_POOL(ctrl, metadata_segment_part_runtime); for (i = 0; i < OCF_USER_IO_CLASS_MAX + 1; i++) { cache->user_parts[i].config = &part_config[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->user_parts[i].clean_pol = &part_runtime[i].clean_pol; + cache->user_parts[i].part.runtime = &part_runtime[i]; } - cache->free.runtime= &part_runtime_meta[PARTITION_FREELIST].runtime; - cache->free_detached.runtime = - &part_runtime_meta[PARTITION_FREE_DETACHED].runtime; + cache->free.runtime = &part_runtime[PARTITION_FREELIST]; + cache->free_detached.runtime = &part_runtime[PARTITION_FREE_DETACHED]; /* Set core metadata */ core_meta_config = METADATA_MEM_POOL(ctrl, diff --git a/src/metadata/metadata.h b/src/metadata/metadata.h index 12a290a6..0b3024d7 100644 --- a/src/metadata/metadata.h +++ b/src/metadata/metadata.h @@ -12,7 +12,7 @@ #include "../ocf_cache_priv.h" #include "../ocf_ctx_priv.h" #include "metadata_cleaning_policy.h" -#include "metadata_eviction_policy.h" +#include "metadata_lru.h" #include "metadata_partition.h" #include "metadata_segment_id.h" #include "metadata_superblock.h" diff --git a/src/metadata/metadata_cleaning_policy.h b/src/metadata/metadata_cleaning_policy.h index f5ae1c0c..549bc0bf 100644 --- a/src/metadata/metadata_cleaning_policy.h +++ b/src/metadata/metadata_cleaning_policy.h @@ -1,11 +1,35 @@ /* * Copyright(c) 2012-2021 Intel Corporation + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __METADATA_CLEANING_POLICY_H__ #define __METADATA_CLEANING_POLICY_H__ +#include "ocf/ocf.h" + +/* Cleaning policy metadata per partition */ + +struct nop_cleaning_policy { +}; + +struct alru_cleaning_policy { + env_atomic size; + uint32_t lru_head; + uint32_t lru_tail; +}; + +struct acp_cleaning_policy { +}; + +struct cleaning_policy { + union { + struct nop_cleaning_policy nop; + struct alru_cleaning_policy alru; + struct acp_cleaning_policy acp; + } policy; +}; struct cleaning_policy_meta * ocf_metadata_get_cleaning_policy(struct ocf_cache *cache, ocf_cache_line_t line); diff --git a/src/metadata/metadata_eviction_policy.c b/src/metadata/metadata_eviction_policy.c index ea42eb2e..985bb598 100644 --- a/src/metadata/metadata_eviction_policy.c +++ b/src/metadata/metadata_eviction_policy.c @@ -1,11 +1,12 @@ /* * Copyright(c) 2020-2021 Intel Corporation + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ #include "ocf/ocf.h" #include "metadata.h" -#include "metadata_eviction_policy.h" +#include "metadata_lru.h" #include "metadata_internal.h" /* diff --git a/src/metadata/metadata_eviction_policy.h b/src/metadata/metadata_eviction_policy.h deleted file mode 100644 index d01fc152..00000000 --- a/src/metadata/metadata_eviction_policy.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright(c) 2012-2021 Intel Corporation - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef __METADATA_EVICTION_H__ -#define __METADATA_EVICTION_H__ - -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/ocf_lru_structs.h b/src/metadata/metadata_lru.h similarity index 74% rename from src/ocf_lru_structs.h rename to src/metadata/metadata_lru.h index 33adaf39..58d17284 100644 --- a/src/ocf_lru_structs.h +++ b/src/metadata/metadata_lru.h @@ -4,9 +4,13 @@ * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef __EVICTION_LRU_STRUCTS_H__ -#define __EVICTION_LRU_STRUCTS_H__ +#ifndef __METADATA_LRU_H__ +#define __METADATA_LRU_H__ + +#include "ocf/ocf.h" + +#define OCF_NUM_LRU_LISTS 32 struct ocf_lru_meta { uint64_t prev : OCF_CACHE_LINE_BITS; @@ -31,6 +35,8 @@ struct ocf_lru_part_meta { struct ocf_lru_list dirty; }; -#define OCF_LRU_HOT_RATIO 2 +struct ocf_lru_meta * +ocf_metadata_get_lru( + struct ocf_cache *cache, ocf_cache_line_t line); -#endif +#endif /* __METADATA_LRU_H__ */ diff --git a/src/metadata/metadata_partition.h b/src/metadata/metadata_partition.h index 6f020437..2755743d 100644 --- a/src/metadata/metadata_partition.h +++ b/src/metadata/metadata_partition.h @@ -8,7 +8,9 @@ #ifndef __METADATA_PARTITION_H__ #define __METADATA_PARTITION_H__ -#include "../ocf_cache_priv.h" +#include "ocf/ocf.h" +#include "metadata_lru.h" +#include "metadata_cleaning_policy.h" #define PARTITION_UNSPECIFIED ((ocf_part_id_t)-1) #define PARTITION_FREELIST (OCF_USER_IO_CLASS_MAX + 1) @@ -16,6 +18,31 @@ #define PARTITION_SIZE_MIN 0 #define PARTITION_SIZE_MAX 100 +#define OCF_NUM_PARTITIONS (OCF_USER_IO_CLASS_MAX + 3) + +struct ocf_user_part_config { + char name[OCF_IO_CLASS_NAME_MAX]; + uint32_t min_size; + uint32_t max_size; + struct { + uint8_t valid : 1; + uint8_t added : 1; + uint8_t eviction : 1; + /*!< This bits is setting during partition sorting, + * and means that can evict from this partition + */ + } flags; + int16_t priority; + ocf_cache_mode_t cache_mode; +}; + +struct ocf_part_runtime { + env_atomic curr_size; + env_atomic evict_counter; + struct ocf_lru_part_meta lru[OCF_NUM_LRU_LISTS]; + struct cleaning_policy clean_pol; +}; + ocf_part_id_t ocf_metadata_get_partition_id(struct ocf_cache *cache, ocf_cache_line_t line); diff --git a/src/ocf_lru.h b/src/ocf_lru.h index 840461b7..5f2b368d 100644 --- a/src/ocf_lru.h +++ b/src/ocf_lru.h @@ -8,7 +8,9 @@ #define __EVICTION_LRU_H__ #include "ocf_space.h" -#include "ocf_lru_structs.h" +#include "metadata/metadata_lru.h" + +#define OCF_LRU_HOT_RATIO 2 struct ocf_part; struct ocf_user_part; diff --git a/src/ocf_part.h b/src/ocf_part.h index c1b692bf..76489e0b 100644 --- a/src/ocf_part.h +++ b/src/ocf_part.h @@ -13,30 +13,7 @@ #include "cleaning/cleaning.h" #include "ocf_space.h" #include "ocf_env_refcnt.h" - -#define OCF_NUM_PARTITIONS (OCF_USER_IO_CLASS_MAX + 3) - -struct ocf_user_part_config { - char name[OCF_IO_CLASS_NAME_MAX]; - uint32_t min_size; - uint32_t max_size; - struct { - uint8_t valid : 1; - uint8_t added : 1; - uint8_t eviction : 1; - /*!< This bits is setting during partition sorting, - * and means that can evict from this partition - */ - } flags; - int16_t priority; - ocf_cache_mode_t cache_mode; -}; - -struct ocf_part_runtime { - env_atomic curr_size; - env_atomic evict_counter; - struct ocf_lru_part_meta lru[OCF_NUM_LRU_LISTS]; -}; +#include "metadata/metadata_partition.h" typedef bool ( *_lru_hash_locked_pfn)(struct ocf_request *req, ocf_core_id_t core_id, uint64_t core_line); diff --git a/src/ocf_space.h b/src/ocf_space.h index 467ce8f5..d9fe2582 100644 --- a/src/ocf_space.h +++ b/src/ocf_space.h @@ -10,9 +10,8 @@ #include "ocf/ocf.h" #include "ocf_lru.h" -#include "ocf_lru_structs.h" +#include "metadata/metadata_lru.h" -#define OCF_NUM_LRU_LISTS 32 #define OCF_LRU_CHUNK_SIZE 256 #define OCF_LRU_STRIPE_SIZE (OCF_NUM_LRU_LISTS * OCF_LRU_CHUNK_SIZE) From 793105b61bc88c38db03218bea0560c218188935 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Sun, 4 Oct 2026 11:13:58 +0200 Subject: [PATCH 3/8] metadata: Isolate cleaning metadata structures Move all the dependencies of cleaning segment to src/metadata/. Signed-off-by: Robert Baldyga --- src/cleaning/acp_structs.h | 6 +----- src/cleaning/alru_structs.h | 7 ------- src/cleaning/cleaning.h | 9 --------- src/cleaning/nop_structs.h | 2 -- src/metadata/metadata_cleaning_policy.h | 26 +++++++++++++++++++++++++ 5 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/cleaning/acp_structs.h b/src/cleaning/acp_structs.h index 3467481f..7db20a4c 100644 --- a/src/cleaning/acp_structs.h +++ b/src/cleaning/acp_structs.h @@ -1,6 +1,7 @@ /* * Copyright(c) 2012-2021 Intel Corporation * Copyright(c) 2023-2025 Huawei Technologies Co., Ltd. + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __CLEANING_AGGRESSIVE_STRUCTS_H__ @@ -8,11 +9,6 @@ #include "ocf_env_headers.h" -/* TODO: remove acp metadata */ -struct acp_cleaning_policy_meta { - uint8_t dirty : 1; -}; - /* cleaning policy per partition metadata */ struct acp_cleaning_policy_config { uint32_t thread_wakeup_time; /* in milliseconds*/ diff --git a/src/cleaning/alru_structs.h b/src/cleaning/alru_structs.h index b8a810ba..6ece3f2a 100644 --- a/src/cleaning/alru_structs.h +++ b/src/cleaning/alru_structs.h @@ -11,13 +11,6 @@ #include "ocf/ocf.h" #include "ocf_env.h" -struct alru_cleaning_policy_meta { - /* Lru pointers 2*4=8 bytes */ - uint32_t timestamp; - uint32_t lru_prev; - uint32_t lru_next; -} __attribute__((packed)); - struct alru_cleaning_policy_config { uint32_t thread_wakeup_time; /* in seconds */ uint32_t stale_buffer_time; /* in seconds */ diff --git a/src/cleaning/cleaning.h b/src/cleaning/cleaning.h index fcb3b719..f3ca448a 100644 --- a/src/cleaning/cleaning.h +++ b/src/cleaning/cleaning.h @@ -26,15 +26,6 @@ struct cleaning_policy_config { uint8_t data[CLEANING_POLICY_CONFIG_BYTES]; } __attribute__((aligned(4))); -/* Cleaning policy metadata per cache line */ -struct cleaning_policy_meta { - union { - struct nop_cleaning_policy_meta nop; - struct alru_cleaning_policy_meta alru; - struct acp_cleaning_policy_meta acp; - } meta; -}; - struct ocf_cleaner { struct env_refcnt refcnt; ocf_cleaning_t policy; diff --git a/src/cleaning/nop_structs.h b/src/cleaning/nop_structs.h index 5f30d00c..93be0d79 100644 --- a/src/cleaning/nop_structs.h +++ b/src/cleaning/nop_structs.h @@ -7,7 +7,5 @@ #define __LAYER_CLEANING_POLICY_NOP_STRUCTS_H__ -struct nop_cleaning_policy_meta { -} __attribute__((packed)); #endif diff --git a/src/metadata/metadata_cleaning_policy.h b/src/metadata/metadata_cleaning_policy.h index 549bc0bf..f0fa3d0d 100644 --- a/src/metadata/metadata_cleaning_policy.h +++ b/src/metadata/metadata_cleaning_policy.h @@ -30,6 +30,32 @@ struct cleaning_policy { struct acp_cleaning_policy acp; } policy; }; + +/* Cleaning policy metadata per cache line */ + +struct nop_cleaning_policy_meta { +} __attribute__((packed)); + +struct alru_cleaning_policy_meta { + /* Lru pointers 2*4=8 bytes */ + uint32_t timestamp; + uint32_t lru_prev; + uint32_t lru_next; +} __attribute__((packed)); + +/* TODO: remove acp metadata */ +struct acp_cleaning_policy_meta { + uint8_t dirty : 1; +}; + +struct cleaning_policy_meta { + union { + struct nop_cleaning_policy_meta nop; + struct alru_cleaning_policy_meta alru; + struct acp_cleaning_policy_meta acp; + } meta; +}; + struct cleaning_policy_meta * ocf_metadata_get_cleaning_policy(struct ocf_cache *cache, ocf_cache_line_t line); From 62633d1d616f70fa44875ef048b40cc926d856d4 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Sun, 4 Oct 2026 11:38:57 +0200 Subject: [PATCH 4/8] metadata: Isolate core metadata structures Move all the dependencies of core_config, core_runtime and uuid segments to src/metadata/. Signed-off-by: Robert Baldyga --- src/metadata/metadata_core.h | 57 +++++++++++++++++++++++++++++++++++- src/ocf_core_priv.h | 56 +---------------------------------- 2 files changed, 57 insertions(+), 56 deletions(-) diff --git a/src/metadata/metadata_core.h b/src/metadata/metadata_core.h index 9776a902..e57dea05 100644 --- a/src/metadata/metadata_core.h +++ b/src/metadata/metadata_core.h @@ -7,7 +7,62 @@ #ifndef __METADATA_CORE_H__ #define __METADATA_CORE_H__ -#include +#include "ocf/ocf.h" + +struct ocf_metadata_uuid { + uint32_t size; + uint8_t data[OCF_VOLUME_UUID_MAX_SIZE]; +} __packed; + +struct ocf_core_meta_config { + char name[OCF_CORE_NAME_SIZE]; + + uint8_t type; + + /* This bit means that object was saved in cache metadata */ + uint32_t valid : 1; + + /* Core sequence number used to correlate cache lines with cores + * when recovering from atomic device */ + ocf_seq_no_t seq_no; + + /* Sequential cutoff threshold (in bytes) */ + env_atomic seq_cutoff_threshold; + + /* Sequential cutoff policy */ + env_atomic seq_cutoff_policy; + + /* Sequence detector stream promotion request count */ + env_atomic seq_detect_promotion_count; + + /* Sequence detector stream promotion threshold (in bytes) */ + env_atomic seq_detect_promotion_threshold; + + /* core object size in bytes */ + uint64_t length; + + uint8_t user_data[OCF_CORE_USER_DATA_SIZE]; +}; + +struct ocf_core_meta_runtime { + /* Number of blocks from that objects that currently are cached + * on the caching device. + */ + env_atomic cached_clines; + env_atomic dirty_clines; + env_atomic initial_dirty_clines; + + env_atomic64 dirty_since; + + struct { + /* clines within lru list (?) */ + env_atomic cached_clines; + /* dirty clines assigned to this specific partition within + * cache device + */ + env_atomic dirty_clines; + } part_counters[OCF_USER_IO_CLASS_MAX]; +}; void ocf_metadata_get_core_info(struct ocf_cache *cache, ocf_cache_line_t line, ocf_core_id_t *core_id, diff --git a/src/ocf_core_priv.h b/src/ocf_core_priv.h index e21746f5..b91c61f7 100644 --- a/src/ocf_core_priv.h +++ b/src/ocf_core_priv.h @@ -14,6 +14,7 @@ #include "ocf_volume_priv.h" #include "ocf_seq_detect.h" #include "ocf/ocf_prefetch.h" +#include "metadata/metadata_core.h" #define ocf_core_log_prefix(core, lvl, prefix, fmt, ...) \ ocf_cache_log_prefix(ocf_core_get_cache(core), lvl, ".%s" prefix, \ @@ -22,61 +23,6 @@ #define ocf_core_log(core, lvl, fmt, ...) \ ocf_core_log_prefix(core, lvl, ": ", fmt, ##__VA_ARGS__) -struct ocf_metadata_uuid { - uint32_t size; - uint8_t data[OCF_VOLUME_UUID_MAX_SIZE]; -} __packed; - -struct ocf_core_meta_config { - char name[OCF_CORE_NAME_SIZE]; - - uint8_t type; - - /* This bit means that object was saved in cache metadata */ - uint32_t valid : 1; - - /* Core sequence number used to correlate cache lines with cores - * when recovering from atomic device */ - ocf_seq_no_t seq_no; - - /* Sequential cutoff threshold (in bytes) */ - env_atomic seq_cutoff_threshold; - - /* Sequential cutoff policy */ - env_atomic seq_cutoff_policy; - - /* Sequence detector stream promotion request count */ - env_atomic seq_detect_promotion_count; - - /* Sequence detector stream promotion threshold (in bytes) */ - env_atomic seq_detect_promotion_threshold; - - /* core object size in bytes */ - uint64_t length; - - uint8_t user_data[OCF_CORE_USER_DATA_SIZE]; -}; - -struct ocf_core_meta_runtime { - /* Number of blocks from that objects that currently are cached - * on the caching device. - */ - env_atomic cached_clines; - env_atomic dirty_clines; - env_atomic initial_dirty_clines; - - env_atomic64 dirty_since; - - struct { - /* clines within lru list (?) */ - env_atomic cached_clines; - /* dirty clines assigned to this specific partition within - * cache device - */ - env_atomic dirty_clines; - } part_counters[OCF_USER_IO_CLASS_MAX]; -}; - struct ocf_core_volume_uuid { char cache_name[OCF_CACHE_NAME_SIZE]; char core_name[OCF_CORE_NAME_SIZE]; From 0830badaa962930389b6f36ed3710d4535ab34f2 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Sun, 4 Oct 2026 12:04:39 +0200 Subject: [PATCH 5/8] metadata: Isolate superblock metadata structures Move all the dependencies of sb_config segment to src/metadata/. Signed-off-by: Robert Baldyga --- src/cleaning/acp_structs.h | 7 +----- src/cleaning/alru_structs.h | 11 +------- src/cleaning/cleaning.h | 7 ------ src/metadata/metadata_cleaning_policy.h | 23 +++++++++++++++++ src/metadata/metadata_prefetch_policy.h | 26 +++++++++++++++++++ src/metadata/metadata_promotion_policy.h | 29 ++++++++++++++++++++++ src/metadata/metadata_segment_id.h | 2 +- src/metadata/metadata_structs.h | 9 +------ src/metadata/metadata_superblock.h | 22 ++++++++++++---- src/prefetch/ocf_prefetch_priv.h | 8 +----- src/prefetch/ocf_prefetch_readahead_priv.h | 4 --- src/promotion/nhit/nhit_structs.h | 9 ++----- src/promotion/promotion.h | 10 ++------ 13 files changed, 104 insertions(+), 63 deletions(-) create mode 100644 src/metadata/metadata_prefetch_policy.h create mode 100644 src/metadata/metadata_promotion_policy.h diff --git a/src/cleaning/acp_structs.h b/src/cleaning/acp_structs.h index 7db20a4c..ca29f8f6 100644 --- a/src/cleaning/acp_structs.h +++ b/src/cleaning/acp_structs.h @@ -7,13 +7,8 @@ #ifndef __CLEANING_AGGRESSIVE_STRUCTS_H__ #define __CLEANING_AGGRESSIVE_STRUCTS_H__ -#include "ocf_env_headers.h" +#include "../metadata/metadata_cleaning_policy.h" -/* cleaning policy per partition metadata */ -struct acp_cleaning_policy_config { - uint32_t thread_wakeup_time; /* in milliseconds*/ - uint32_t flush_max_buffers; /* in lines */ -}; #endif diff --git a/src/cleaning/alru_structs.h b/src/cleaning/alru_structs.h index 6ece3f2a..7df658c2 100644 --- a/src/cleaning/alru_structs.h +++ b/src/cleaning/alru_structs.h @@ -8,17 +8,8 @@ #ifndef __CLEANING_ALRU_STRUCTS_H__ #define __CLEANING_ALRU_STRUCTS_H__ -#include "ocf/ocf.h" -#include "ocf_env.h" +#include "../metadata/metadata_cleaning_policy.h" -struct alru_cleaning_policy_config { - uint32_t thread_wakeup_time; /* in seconds */ - uint32_t stale_buffer_time; /* in seconds */ - uint32_t flush_max_buffers; /* in lines */ - uint32_t activity_threshold; /* in milliseconds */ - uint32_t dirty_ratio_threshold; /* percent */ - uint32_t dirty_ratio_inertia; /* bytes */ -}; #endif diff --git a/src/cleaning/cleaning.h b/src/cleaning/cleaning.h index f3ca448a..5a022043 100644 --- a/src/cleaning/cleaning.h +++ b/src/cleaning/cleaning.h @@ -15,17 +15,10 @@ #include "ocf_env_refcnt.h" #include "ocf/ocf_cleaner.h" -#define CLEANING_POLICY_CONFIG_BYTES 256 -#define CLEANING_POLICY_TYPE_MAX 4 - #define SLEEP_TIME_MS (1000) struct ocf_request; -struct cleaning_policy_config { - uint8_t data[CLEANING_POLICY_CONFIG_BYTES]; -} __attribute__((aligned(4))); - struct ocf_cleaner { struct env_refcnt refcnt; ocf_cleaning_t policy; diff --git a/src/metadata/metadata_cleaning_policy.h b/src/metadata/metadata_cleaning_policy.h index f0fa3d0d..ddc7cb9e 100644 --- a/src/metadata/metadata_cleaning_policy.h +++ b/src/metadata/metadata_cleaning_policy.h @@ -9,6 +9,29 @@ #include "ocf/ocf.h" +/* Cleaning policy configuration (stored in superblock) */ + +#define CLEANING_POLICY_CONFIG_BYTES 256 +#define CLEANING_POLICY_TYPE_MAX 4 + +struct cleaning_policy_config { + uint8_t data[CLEANING_POLICY_CONFIG_BYTES]; +} __attribute__((aligned(4))); + +struct alru_cleaning_policy_config { + uint32_t thread_wakeup_time; /* in seconds */ + uint32_t stale_buffer_time; /* in seconds */ + uint32_t flush_max_buffers; /* in lines */ + uint32_t activity_threshold; /* in milliseconds */ + uint32_t dirty_ratio_threshold; /* percent */ + uint32_t dirty_ratio_inertia; /* bytes */ +}; + +struct acp_cleaning_policy_config { + uint32_t thread_wakeup_time; /* in milliseconds*/ + uint32_t flush_max_buffers; /* in lines */ +}; + /* Cleaning policy metadata per partition */ struct nop_cleaning_policy { diff --git a/src/metadata/metadata_prefetch_policy.h b/src/metadata/metadata_prefetch_policy.h new file mode 100644 index 00000000..e228ce50 --- /dev/null +++ b/src/metadata/metadata_prefetch_policy.h @@ -0,0 +1,26 @@ +/* + * Copyright(c) 2022-2024 Huawei Technologies + * Copyright(c) 2026 Unvertical + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __METADATA_PREFETCH_POLICY_H__ +#define __METADATA_PREFETCH_POLICY_H__ + +#include "ocf/ocf.h" +#include "ocf/ocf_prefetch.h" + +/* Prefetch policy configuration (stored in superblock) */ + +#define PREFETCH_POLICY_CONFIG_BYTES 256 +#define PREFETCH_POLICY_TYPE_MAX ((int)ocf_pf_num) + +struct prefetch_policy_config { + uint8_t data[PREFETCH_POLICY_CONFIG_BYTES]; +} __attribute__((aligned(4))); + +struct readahead_prefetch_policy_config { + uint32_t threshold; /* in bytes */ +}; + +#endif /* __METADATA_PREFETCH_POLICY_H__ */ diff --git a/src/metadata/metadata_promotion_policy.h b/src/metadata/metadata_promotion_policy.h new file mode 100644 index 00000000..5af84b5b --- /dev/null +++ b/src/metadata/metadata_promotion_policy.h @@ -0,0 +1,29 @@ +/* + * Copyright(c) 2012-2021 Intel Corporation + * Copyright(c) 2026 Unvertical + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __METADATA_PROMOTION_POLICY_H__ +#define __METADATA_PROMOTION_POLICY_H__ + +#include "ocf/ocf.h" + +/* Promotion policy configuration (stored in superblock) */ + +#define PROMOTION_POLICY_CONFIG_BYTES 256 +#define PROMOTION_POLICY_TYPE_MAX 2 + +struct promotion_policy_config { + uint8_t data[PROMOTION_POLICY_CONFIG_BYTES]; +} __attribute__((aligned(4))); + +struct nhit_promotion_policy_config { + uint32_t insertion_threshold; + /*!< Number of hits */ + + uint32_t trigger_threshold; + /*!< Cache occupancy (percentage value) */ +}; + +#endif /* __METADATA_PROMOTION_POLICY_H__ */ diff --git a/src/metadata/metadata_segment_id.h b/src/metadata/metadata_segment_id.h index 8d08877e..55bcf02d 100644 --- a/src/metadata/metadata_segment_id.h +++ b/src/metadata/metadata_segment_id.h @@ -1,5 +1,6 @@ /* * Copyright(c) 2012-2021 Intel Corporation + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +12,6 @@ * @brief Metadata Service - Hash Implementation */ -#include "../ocf_request.h" /** * @brief Metada hash elements type */ diff --git a/src/metadata/metadata_structs.h b/src/metadata/metadata_structs.h index dd4f548b..dbecac47 100644 --- a/src/metadata/metadata_structs.h +++ b/src/metadata/metadata_structs.h @@ -12,6 +12,7 @@ #include "../ocf_space.h" #include "../cleaning/cleaning.h" #include "../ocf_request.h" +#include "metadata_superblock.h" /** @@ -19,14 +20,6 @@ * @brief Metadata private structures */ -/** - * @brief Metadata shutdown status - */ -enum ocf_metadata_shutdown_status { - ocf_metadata_dirty_shutdown = 0, /*!< Dirty OCF shutdown*/ - ocf_metadata_clean_shutdown = 1, /*!< OCF shutdown graceful*/ -}; - /** * @brief Query cores completion callback * diff --git a/src/metadata/metadata_superblock.h b/src/metadata/metadata_superblock.h index a01f23fc..d8098d7b 100644 --- a/src/metadata/metadata_superblock.h +++ b/src/metadata/metadata_superblock.h @@ -8,14 +8,24 @@ #ifndef __METADATA_SUPERBLOCK_H__ #define __METADATA_SUPERBLOCK_H__ -#include -#include "metadata_segment.h" -#include "../promotion/promotion.h" -#include "ocf/ocf_prefetch.h" -#include "../prefetch/ocf_prefetch_priv.h" +#include "ocf/ocf.h" +#include "../ocf_def_priv.h" +#include "metadata_common.h" +#include "metadata_segment_id.h" +#include "metadata_cleaning_policy.h" +#include "metadata_promotion_policy.h" +#include "metadata_prefetch_policy.h" #define CACHE_MAGIC_NUMBER 0x187E1CA6 +/** + * @brief Metadata shutdown status + */ +enum ocf_metadata_shutdown_status { + ocf_metadata_dirty_shutdown = 0, /*!< Dirty OCF shutdown*/ + ocf_metadata_clean_shutdown = 1, /*!< OCF shutdown graceful*/ +}; + /** * @brief OCF cache metadata configuration superblock * @@ -92,6 +102,8 @@ struct ocf_superblock_runtime { }; struct ocf_metadata_ctrl; +struct ocf_metadata_segment; +struct ocf_metadata_raw; void ocf_metadata_set_shutdown_status(ocf_cache_t cache, enum ocf_metadata_shutdown_status shutdown_status, diff --git a/src/prefetch/ocf_prefetch_priv.h b/src/prefetch/ocf_prefetch_priv.h index 5f36a9b0..0bafd7a8 100644 --- a/src/prefetch/ocf_prefetch_priv.h +++ b/src/prefetch/ocf_prefetch_priv.h @@ -11,16 +11,10 @@ #include "../ocf_request.h" #include "ocf/ocf_types.h" #include "ocf/ocf_def.h" +#include "../metadata/metadata_prefetch_policy.h" #define OCF_PF_MAX_TOTAL (8 * MiB) -#define PREFETCH_POLICY_CONFIG_BYTES 256 -#define PREFETCH_POLICY_TYPE_MAX ((int)ocf_pf_num) - -struct prefetch_policy_config { - uint8_t data[PREFETCH_POLICY_CONFIG_BYTES]; -} __attribute__((aligned(4))); - #define OCF_PF_ID_VALID(pf_id) ((pf_id) != ocf_pf_none && (pf_id) < ocf_pf_num) #define OCF_PF_ID_ENABLED(pf_id, enabled_mask) ((1 << ((pf_id))) & enabled_mask) diff --git a/src/prefetch/ocf_prefetch_readahead_priv.h b/src/prefetch/ocf_prefetch_readahead_priv.h index 06d56215..cfe2e7e8 100644 --- a/src/prefetch/ocf_prefetch_readahead_priv.h +++ b/src/prefetch/ocf_prefetch_readahead_priv.h @@ -11,10 +11,6 @@ #include "ocf/ocf_types.h" #include "ocf_env.h" -struct readahead_prefetch_policy_config { - uint32_t threshold; /* in bytes */ -}; - void ocf_pf_readahead_setup(ocf_cache_t cache); int ocf_pf_readahead_init(ocf_core_t core); void ocf_pf_readahead_deinit(ocf_core_t core); diff --git a/src/promotion/nhit/nhit_structs.h b/src/promotion/nhit/nhit_structs.h index 69ddce9e..3b614e43 100644 --- a/src/promotion/nhit/nhit_structs.h +++ b/src/promotion/nhit/nhit_structs.h @@ -1,16 +1,11 @@ /* * Copyright(c) 2012-2021 Intel Corporation + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __PROMOTION_NHIT_STRUCTS_H_ #define __PROMOTION_NHIT_STRUCTS_H_ -struct nhit_promotion_policy_config { - uint32_t insertion_threshold; - /*!< Number of hits */ - - uint32_t trigger_threshold; - /*!< Cache occupancy (percentage value) */ -}; +#include "../../metadata/metadata_promotion_policy.h" #endif diff --git a/src/promotion/promotion.h b/src/promotion/promotion.h index 612b5b62..684c1e84 100644 --- a/src/promotion/promotion.h +++ b/src/promotion/promotion.h @@ -1,5 +1,6 @@ /* * Copyright(c) 2019-2021 Intel Corporation + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,14 +9,7 @@ #include "ocf/ocf.h" #include "../ocf_request.h" - -#define PROMOTION_POLICY_CONFIG_BYTES 256 -#define PROMOTION_POLICY_TYPE_MAX 2 - - -struct promotion_policy_config { - uint8_t data[PROMOTION_POLICY_CONFIG_BYTES]; -} __attribute__((aligned(4))); +#include "../metadata/metadata_promotion_policy.h" typedef struct ocf_promotion_policy *ocf_promotion_policy_t; From 7c9fe197a63cd9eceeb8a3fdea36c62b2c64c961 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Sun, 4 Oct 2026 14:17:06 +0200 Subject: [PATCH 6/8] metadata: Clarify collision API Move the functions to right headers and decouple metadata structs from runtime internals. Signed-off-by: Robert Baldyga --- src/metadata/metadata.c | 272 +--------------- src/metadata/metadata_bit.h | 520 +++++++++++++++++------------- src/metadata/metadata_collision.c | 59 ++++ src/metadata/metadata_collision.h | 14 + src/metadata/metadata_core.c | 55 ---- src/metadata/metadata_core.h | 11 - 6 files changed, 374 insertions(+), 557 deletions(-) diff --git a/src/metadata/metadata.c b/src/metadata/metadata.c index cfe73890..f8772082 100644 --- a/src/metadata/metadata.c +++ b/src/metadata/metadata.c @@ -8,6 +8,7 @@ #include "ocf/ocf.h" #include "metadata.h" +#include "metadata_bit.h" #include "metadata_collision.h" #include "metadata_segment_id.h" #include "metadata_internal.h" @@ -38,45 +39,6 @@ #define OCF_METADATA_HASH_DIFF_MAX 1000 -enum { - ocf_metadata_status_type_valid = 0, - ocf_metadata_status_type_dirty, - - ocf_metadata_status_type_max -}; - -static inline size_t ocf_metadata_status_sizeof(ocf_cache_line_size_t line_size) -{ - size_t size; - - switch (line_size) { - case ocf_cache_line_size_4: -#ifdef OCF_BLOCK_SIZE_4K - /* - * We only need one valid and one dirty per line. - * Use bitfields from struct ocf_metadata_map. - */ - size = 0; - break; -#endif - case ocf_cache_line_size_8: - case ocf_cache_line_size_16: - case ocf_cache_line_size_32: - case ocf_cache_line_size_64: - /* Number of bytes required to mark cache line status */ - size = OCF_DIV_ROUND_UP(BYTES_TO_BLOCKS(line_size), 8); - break; - default: - ENV_BUG(); - } - - /* Number of types of status (valid, dirty, etc...) */ - size *= ocf_metadata_status_type_max; - - /* At the end we have size */ - return size; -} - /* * get entries for specified metadata hash type */ @@ -1522,14 +1484,9 @@ void ocf_metadata_get_core_and_part_id(struct ocf_cache *cache, { const struct ocf_metadata_map *collision; 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_lru]), line); + collision = ocf_metadata_get_collision(cache, line); + info = ocf_metadata_get_lru(cache, line); ENV_BUG_ON(!collision || !info); @@ -1580,102 +1537,21 @@ void ocf_metadata_set_hash(struct ocf_cache *cache, ocf_cache_line_t index, * Bitmap status ******************************************************************************/ -#include "metadata_bit.h" - -#ifdef OCF_BLOCK_SIZE_4K -#define _ocf_metadata_funcs_5arg(what) \ -bool ocf_metadata_##what(struct ocf_cache *cache, \ - ocf_cache_line_t line, uint8_t start, uint8_t stop, bool all) \ -{ \ - switch (cache->metadata.line_size) { \ - case ocf_cache_line_size_4: \ - return _ocf_metadata_##what(cache, line, start, stop, all); \ - case ocf_cache_line_size_8: \ - case ocf_cache_line_size_16: \ - case ocf_cache_line_size_32: \ - return _ocf_metadata_##what##_u8(cache, line, \ - start, stop, all); \ - case ocf_cache_line_size_64: \ - return _ocf_metadata_##what##_u16(cache, line, \ - start, stop, all); \ - case ocf_cache_line_size_none: \ - default: \ - ENV_BUG_ON(1); \ - return false; \ - } \ -} -#else #define _ocf_metadata_funcs_5arg(what) \ bool ocf_metadata_##what(struct ocf_cache *cache, \ ocf_cache_line_t line, uint8_t start, uint8_t stop, bool all) \ { \ - switch (cache->metadata.line_size) { \ - case ocf_cache_line_size_4: \ - return _ocf_metadata_##what##_u8(cache, line, \ - start, stop, all); \ - case ocf_cache_line_size_8: \ - return _ocf_metadata_##what##_u16(cache, line, \ - start, stop, all); \ - case ocf_cache_line_size_16: \ - return _ocf_metadata_##what##_u32(cache, line, \ - start, stop, all); \ - case ocf_cache_line_size_32: \ - return _ocf_metadata_##what##_u64(cache, line, \ - start, stop, all); \ - case ocf_cache_line_size_64: \ - return _ocf_metadata_##what##_u128(cache, line, \ - start, stop, all); \ - case ocf_cache_line_size_none: \ - default: \ - ENV_BUG_ON(1); \ - return false; \ - } \ + return ocf_metadata_bit_##what(ocf_metadata_get_collision(cache, line), \ + cache->metadata.line_size, start, stop, all); \ } -#endif -#ifdef OCF_BLOCK_SIZE_4K #define _ocf_metadata_funcs_4arg(what) \ bool ocf_metadata_##what(struct ocf_cache *cache, \ ocf_cache_line_t line, uint8_t start, uint8_t stop) \ { \ - switch (cache->metadata.line_size) { \ - case ocf_cache_line_size_4: \ - return _ocf_metadata_##what(cache, line, start, stop); \ - case ocf_cache_line_size_8: \ - case ocf_cache_line_size_16: \ - case ocf_cache_line_size_32: \ - return _ocf_metadata_##what##_u8(cache, line, start, stop); \ - case ocf_cache_line_size_64: \ - return _ocf_metadata_##what##_u16(cache, line, start, stop); \ - case ocf_cache_line_size_none: \ - default: \ - ENV_BUG_ON(1); \ - return false; \ - } \ + return ocf_metadata_bit_##what(ocf_metadata_get_collision(cache, line), \ + cache->metadata.line_size, start, stop); \ } -#else -#define _ocf_metadata_funcs_4arg(what) \ -bool ocf_metadata_##what(struct ocf_cache *cache, \ - ocf_cache_line_t line, uint8_t start, uint8_t stop) \ -{ \ - switch (cache->metadata.line_size) { \ - case ocf_cache_line_size_4: \ - return _ocf_metadata_##what##_u8(cache, line, start, stop); \ - case ocf_cache_line_size_8: \ - return _ocf_metadata_##what##_u16(cache, line, start, stop); \ - case ocf_cache_line_size_16: \ - return _ocf_metadata_##what##_u32(cache, line, start, stop); \ - case ocf_cache_line_size_32: \ - return _ocf_metadata_##what##_u64(cache, line, start, stop); \ - case ocf_cache_line_size_64: \ - return _ocf_metadata_##what##_u128(cache, line, start, stop); \ - case ocf_cache_line_size_none: \ - default: \ - ENV_BUG_ON(1); \ - return false; \ - } \ -} -#endif #define _ocf_metadata_funcs(what) \ _ocf_metadata_funcs_5arg(test_##what) \ @@ -1688,143 +1564,21 @@ bool ocf_metadata_##what(struct ocf_cache *cache, \ _ocf_metadata_funcs(dirty) _ocf_metadata_funcs(valid) -#ifdef OCF_BLOCK_SIZE_4K -bool ocf_metadata_clear_valid_if_clean(struct ocf_cache *cache, - ocf_cache_line_t line, uint8_t start, uint8_t stop) -{ - switch (cache->metadata.line_size) { - case ocf_cache_line_size_4: - return _ocf_metadata_clear_valid_if_clean(cache, - line, start, stop); - case ocf_cache_line_size_8: - case ocf_cache_line_size_16: - case ocf_cache_line_size_32: - return _ocf_metadata_clear_valid_if_clean_u8(cache, - line, start, stop); - case ocf_cache_line_size_64: - return _ocf_metadata_clear_valid_if_clean_u16(cache, - line, start, stop); - case ocf_cache_line_size_none: - default: - ENV_BUG_ON(1); - return false; - } -} -#else -bool ocf_metadata_clear_valid_if_clean(struct ocf_cache *cache, - ocf_cache_line_t line, uint8_t start, uint8_t stop) -{ - switch (cache->metadata.line_size) { - case ocf_cache_line_size_4: - return _ocf_metadata_clear_valid_if_clean_u8(cache, - line, start, stop); - case ocf_cache_line_size_8: - return _ocf_metadata_clear_valid_if_clean_u16(cache, - line, start, stop); - case ocf_cache_line_size_16: - return _ocf_metadata_clear_valid_if_clean_u32(cache, - line, start, stop); - case ocf_cache_line_size_32: - return _ocf_metadata_clear_valid_if_clean_u64(cache, - line, start, stop); - case ocf_cache_line_size_64: - return _ocf_metadata_clear_valid_if_clean_u128(cache, - line, start, stop); - case ocf_cache_line_size_none: - default: - ENV_BUG_ON(1); - return false; - } -} -#endif +_ocf_metadata_funcs_4arg(clear_valid_if_clean) -#ifdef OCF_BLOCK_SIZE_4K -void ocf_metadata_clear_dirty_if_invalid(struct ocf_cache *cache, - ocf_cache_line_t line, uint8_t start, uint8_t stop) -{ - switch (cache->metadata.line_size) { - case ocf_cache_line_size_4: - return _ocf_metadata_clear_dirty_if_invalid(cache, - line, start, stop); - case ocf_cache_line_size_8: - case ocf_cache_line_size_16: - case ocf_cache_line_size_32: - return _ocf_metadata_clear_dirty_if_invalid_u8(cache, - line, start, stop); - case ocf_cache_line_size_64: - return _ocf_metadata_clear_dirty_if_invalid_u16(cache, - line, start, stop); - case ocf_cache_line_size_none: - default: - ENV_BUG(); - } -} -#else void ocf_metadata_clear_dirty_if_invalid(struct ocf_cache *cache, ocf_cache_line_t line, uint8_t start, uint8_t stop) { - switch (cache->metadata.line_size) { - case ocf_cache_line_size_4: - return _ocf_metadata_clear_dirty_if_invalid_u8(cache, - line, start, stop); - case ocf_cache_line_size_8: - return _ocf_metadata_clear_dirty_if_invalid_u16(cache, - line, start, stop); - case ocf_cache_line_size_16: - return _ocf_metadata_clear_dirty_if_invalid_u32(cache, - line, start, stop); - case ocf_cache_line_size_32: - return _ocf_metadata_clear_dirty_if_invalid_u64(cache, - line, start, stop); - case ocf_cache_line_size_64: - return _ocf_metadata_clear_dirty_if_invalid_u128(cache, - line, start, stop); - case ocf_cache_line_size_none: - default: - ENV_BUG(); - } + ocf_metadata_bit_clear_dirty_if_invalid( + ocf_metadata_get_collision(cache, line), + cache->metadata.line_size, start, stop); } -#endif -#ifdef OCF_BLOCK_SIZE_4K bool ocf_metadata_check(struct ocf_cache *cache, ocf_cache_line_t line) { - switch (cache->metadata.line_size) { - case ocf_cache_line_size_4: - return _ocf_metadata_check(cache, line); - case ocf_cache_line_size_8: - case ocf_cache_line_size_16: - case ocf_cache_line_size_32: - return _ocf_metadata_check_u8(cache, line); - case ocf_cache_line_size_64: - return _ocf_metadata_check_u16(cache, line); - case ocf_cache_line_size_none: - default: - ENV_BUG_ON(1); - return false; - } + return ocf_metadata_bit_check(ocf_metadata_get_collision(cache, line), + cache->metadata.line_size); } -#else -bool ocf_metadata_check(struct ocf_cache *cache, ocf_cache_line_t line) -{ - switch (cache->metadata.line_size) { - case ocf_cache_line_size_4: - return _ocf_metadata_check_u8(cache, line); - case ocf_cache_line_size_8: - return _ocf_metadata_check_u16(cache, line); - case ocf_cache_line_size_16: - return _ocf_metadata_check_u32(cache, line); - case ocf_cache_line_size_32: - return _ocf_metadata_check_u64(cache, line); - case ocf_cache_line_size_64: - return _ocf_metadata_check_u128(cache, line); - case ocf_cache_line_size_none: - default: - ENV_BUG_ON(1); - return false; - } -} -#endif int ocf_metadata_init(struct ocf_cache *cache, ocf_cache_line_size_t cache_line_size) diff --git a/src/metadata/metadata_bit.h b/src/metadata/metadata_bit.h index 5c7c5471..01ccaf81 100644 --- a/src/metadata/metadata_bit.h +++ b/src/metadata/metadata_bit.h @@ -5,6 +5,115 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#ifndef __METADATA_BIT_H__ +#define __METADATA_BIT_H__ + +#include "metadata_collision.h" + +/* + * Cache line status bits (valid, dirty) stored in collision segment. + * + * All functions here operate on single collision segment entry and do not + * depend on cache object, so they can be used on any buffer holding + * collision segment, e.g. during metadata migration. + */ + +/******************************************************************************* + * Status layout + ******************************************************************************/ + +/** + * @brief Cache line status types, stored in this order after + * struct ocf_metadata_map + */ +enum { + ocf_metadata_status_type_valid = 0, + ocf_metadata_status_type_dirty, + + ocf_metadata_status_type_max +}; + +/** + * @brief Size of status following struct ocf_metadata_map in collision entry + */ +static inline size_t ocf_metadata_status_sizeof(ocf_cache_line_size_t line_size) +{ + size_t size; + + switch (line_size) { + case ocf_cache_line_size_4: +#ifdef OCF_BLOCK_SIZE_4K + /* + * We only need one valid and one dirty per line. + * Use bitfields from struct ocf_metadata_map. + */ + size = 0; + break; +#endif + case ocf_cache_line_size_8: + case ocf_cache_line_size_16: + case ocf_cache_line_size_32: + case ocf_cache_line_size_64: + /* Number of bytes required to mark cache line status */ + size = OCF_DIV_ROUND_UP(BYTES_TO_BLOCKS(line_size), 8); + break; + default: + ENV_BUG(); + } + + /* Number of types of status (valid, dirty, etc...) */ + size *= ocf_metadata_status_type_max; + + /* At the end we have size */ + return size; +} + +typedef __uint128_t u128; + +/* + * Collision entry layout for each cache line size. Bit N of valid/dirty + * describes block N of the cache line (block size is OCF_BLOCK_SIZE). + * + * line size | OCF_BLOCK_SIZE_4K | default (512B blocks) + * ----------+---------------------------+---------------------- + * 4 KiB | map._valid, map._dirty | ocf_metadata_map_u8 + * 8 KiB | ocf_metadata_map_u8 | ocf_metadata_map_u16 + * 16 KiB | ocf_metadata_map_u8 | ocf_metadata_map_u32 + * 32 KiB | ocf_metadata_map_u8 | ocf_metadata_map_u64 + * 64 KiB | ocf_metadata_map_u16 | ocf_metadata_map_u128 + */ +struct ocf_metadata_map_u8 { + struct ocf_metadata_map map; + u8 valid; + u8 dirty; +} __attribute__((packed)); + +struct ocf_metadata_map_u16 { + struct ocf_metadata_map map; + u16 valid; + u16 dirty; +} __attribute__((packed)); + +#ifndef OCF_BLOCK_SIZE_4K +struct ocf_metadata_map_u32 { + struct ocf_metadata_map map; + u32 valid; + u32 dirty; +} __attribute__((packed)); + +struct ocf_metadata_map_u64 { + struct ocf_metadata_map map; + u64 valid; + u64 dirty; +} __attribute__((packed)); + +struct ocf_metadata_map_u128 { + struct ocf_metadata_map map; + u128 valid; + u128 dirty; +} __attribute__((packed)); +#endif + /******************************************************************************* * Sector mask getter ******************************************************************************/ @@ -29,8 +138,6 @@ static inline uint64_t _get_mask(uint8_t start, uint8_t stop) #define _get_mask_u32(start, stop) _get_mask(start, stop) #define _get_mask_u64(start, stop) _get_mask(start, stop) -typedef __uint128_t u128; - static inline u128 _get_mask_u128(uint8_t start, uint8_t stop) { u128 mask = 0; @@ -46,225 +153,142 @@ static inline u128 _get_mask_u128(uint8_t start, uint8_t stop) return mask; } -#define ocf_metadata_bit_struct(type) \ -struct ocf_metadata_map_##type { \ - struct ocf_metadata_map map; \ - type valid; \ - type dirty; \ -} __attribute__((packed)) +/******************************************************************************* + * Per entry type status operations + ******************************************************************************/ #ifdef OCF_BLOCK_SIZE_4K #define ocf_metadata_bit_func_no_type(what) \ -static bool _ocf_metadata_test_##what(struct ocf_cache *cache, \ - ocf_cache_line_t line, uint8_t start, uint8_t stop, bool all) \ +static inline bool _ocf_metadata_test_##what( \ + const struct ocf_metadata_map *entry, \ + uint8_t start, uint8_t stop, bool all) \ { \ - struct ocf_metadata_ctrl *ctrl = \ - (struct ocf_metadata_ctrl *) cache->metadata.priv; \ -\ - struct ocf_metadata_raw *raw = \ - &ctrl->raw_desc[metadata_segment_collision]; \ -\ - const struct ocf_metadata_map *map = raw->mem_pool; \ -\ ENV_BUG_ON(start != stop); \ \ - _raw_bug_on(raw, line); \ -\ - if (map[line]._##what) { \ + if (entry->_##what) { \ return true; \ } else { \ return false; \ } \ } \ \ -static bool _ocf_metadata_test_out_##what(struct ocf_cache *cache, \ - ocf_cache_line_t line, uint8_t start, uint8_t stop) \ +static inline bool _ocf_metadata_test_out_##what( \ + struct ocf_metadata_map *entry, \ + uint8_t start, uint8_t stop) \ { \ return false; \ } \ \ -static bool _ocf_metadata_clear_##what(struct ocf_cache *cache, \ - ocf_cache_line_t line, uint8_t start, uint8_t stop) \ +static inline bool _ocf_metadata_clear_##what(struct ocf_metadata_map *entry, \ + uint8_t start, uint8_t stop) \ { \ - struct ocf_metadata_ctrl *ctrl = \ - (struct ocf_metadata_ctrl *) cache->metadata.priv; \ -\ - struct ocf_metadata_raw *raw = \ - &ctrl->raw_desc[metadata_segment_collision]; \ -\ - struct ocf_metadata_map *map = raw->mem_pool; \ -\ ENV_BUG_ON(start != stop); \ \ - _raw_bug_on(raw, line); \ -\ - map[line]._##what = 0; \ + entry->_##what = 0; \ \ return false; \ } \ \ -static bool _ocf_metadata_set_##what(struct ocf_cache *cache, \ - ocf_cache_line_t line, uint8_t start, uint8_t stop) \ +static inline bool _ocf_metadata_set_##what(struct ocf_metadata_map *entry, \ + uint8_t start, uint8_t stop) \ { \ bool result; \ -\ - struct ocf_metadata_ctrl *ctrl = \ - (struct ocf_metadata_ctrl *) cache->metadata.priv; \ -\ - struct ocf_metadata_raw *raw = \ - &ctrl->raw_desc[metadata_segment_collision]; \ -\ - struct ocf_metadata_map *map = raw->mem_pool; \ \ ENV_BUG_ON(start != stop); \ - _raw_bug_on(raw, line); \ \ - result = map[line]._##what ? true : false; \ + result = entry->_##what ? true : false; \ \ - map[line]._##what = 1; \ + entry->_##what = 1; \ \ return result; \ } \ \ -static bool _ocf_metadata_test_and_set_##what( \ - struct ocf_cache *cache, ocf_cache_line_t line, \ +static inline bool _ocf_metadata_test_and_set_##what( \ + struct ocf_metadata_map *entry, \ uint8_t start, uint8_t stop, bool all) \ { \ bool test; \ - struct ocf_metadata_ctrl *ctrl = \ - (struct ocf_metadata_ctrl *) cache->metadata.priv; \ -\ - struct ocf_metadata_raw *raw = \ - &ctrl->raw_desc[metadata_segment_collision]; \ -\ - struct ocf_metadata_map *map = raw->mem_pool; \ \ ENV_BUG_ON(start != stop); \ \ - _raw_bug_on(raw, line); \ -\ - if (map[line]._##what) { \ + if (entry->_##what) { \ test = true; \ } else { \ test = false; \ } \ \ - map[line]._##what = 1; \ + entry->_##what = 1; \ return test; \ } \ \ -static bool _ocf_metadata_test_and_clear_##what( \ - struct ocf_cache *cache, ocf_cache_line_t line, \ +static inline bool _ocf_metadata_test_and_clear_##what( \ + struct ocf_metadata_map *entry, \ uint8_t start, uint8_t stop, bool all) \ { \ bool test; \ - struct ocf_metadata_ctrl *ctrl = \ - (struct ocf_metadata_ctrl *) cache->metadata.priv; \ -\ - struct ocf_metadata_raw *raw = \ - &ctrl->raw_desc[metadata_segment_collision]; \ -\ - struct ocf_metadata_map *map = raw->mem_pool; \ \ ENV_BUG_ON(start != stop); \ \ - _raw_bug_on(raw, line); \ -\ - if (map[line]._##what) { \ + if (entry->_##what) { \ test = true; \ } else { \ test = false; \ } \ \ - map[line]._##what = 0; \ + entry->_##what = 0; \ return test; \ } #define ocf_metadata_bit_func_basic_no_type() \ -static bool _ocf_metadata_clear_valid_if_clean(struct ocf_cache *cache, \ - ocf_cache_line_t line, uint8_t start, uint8_t stop) \ +static inline bool _ocf_metadata_clear_valid_if_clean( \ + struct ocf_metadata_map *entry, \ + uint8_t start, uint8_t stop) \ { \ - struct ocf_metadata_ctrl *ctrl = \ - (struct ocf_metadata_ctrl *) cache->metadata.priv; \ -\ - struct ocf_metadata_raw *raw = \ - &ctrl->raw_desc[metadata_segment_collision]; \ -\ - struct ocf_metadata_map *map = raw->mem_pool; \ -\ ENV_BUG_ON(start != stop); \ \ - _raw_bug_on(raw, line); \ + entry->_valid = (!entry->_dirty) ? 0 : entry->_valid; \ \ - map[line]._valid = (!map[line]._dirty) ? 0 : map[line]._valid; \ -\ - if (map[line]._valid) { \ + if (entry->_valid) { \ return true; \ } else { \ return false; \ } \ } \ \ -static void _ocf_metadata_clear_dirty_if_invalid(struct ocf_cache *cache, \ - ocf_cache_line_t line, uint8_t start, uint8_t stop) \ +static inline void _ocf_metadata_clear_dirty_if_invalid( \ + struct ocf_metadata_map *entry, \ + uint8_t start, uint8_t stop) \ { \ - struct ocf_metadata_ctrl *ctrl = \ - (struct ocf_metadata_ctrl *) cache->metadata.priv; \ -\ - struct ocf_metadata_raw *raw = \ - &ctrl->raw_desc[metadata_segment_collision]; \ -\ - struct ocf_metadata_map *map = raw->mem_pool; \ -\ ENV_BUG_ON(start != stop); \ \ - _raw_bug_on(raw, line); \ -\ - map[line]._dirty = (!map[line]._valid) ? 0 : map[line]._dirty; \ + entry->_dirty = (!entry->_valid) ? 0 : entry->_dirty; \ } \ \ /* true if no incorrect combination of status bits */ \ -static bool _ocf_metadata_check(struct ocf_cache *cache, \ - ocf_cache_line_t line) \ +static inline bool _ocf_metadata_check( \ + const struct ocf_metadata_map *entry) \ { \ - struct ocf_metadata_ctrl *ctrl = \ - (struct ocf_metadata_ctrl *) cache->metadata.priv; \ -\ - struct ocf_metadata_raw *raw = \ - &ctrl->raw_desc[metadata_segment_collision]; \ -\ - struct ocf_metadata_map *map = raw->mem_pool; \ -\ - _raw_bug_on(raw, line); \ -\ - return (map[line]._dirty & (!map[line]._valid)) == 0; \ + return (entry->_dirty & (!entry->_valid)) == 0; \ } #endif #define ocf_metadata_bit_func(what, type) \ -static bool _ocf_metadata_test_##what##_##type(struct ocf_cache *cache, \ - ocf_cache_line_t line, uint8_t start, uint8_t stop, bool all) \ +static inline bool _ocf_metadata_test_##what##_##type( \ + const struct ocf_metadata_map *entry, \ + uint8_t start, uint8_t stop, bool all) \ { \ type mask = _get_mask_##type(start, stop); \ \ - struct ocf_metadata_ctrl *ctrl = \ - (struct ocf_metadata_ctrl *) cache->metadata.priv; \ -\ - struct ocf_metadata_raw *raw = \ - &ctrl->raw_desc[metadata_segment_collision]; \ -\ - const struct ocf_metadata_map_##type *map = raw->mem_pool; \ -\ - _raw_bug_on(raw, line); \ + const struct ocf_metadata_map_##type *map = (const void *)entry; \ \ if (all) { \ - if (mask == (map[line].what & mask)) { \ + if (mask == (map->what & mask)) { \ return true; \ } else { \ return false; \ } \ } else { \ - if (map[line].what & mask) { \ + if (map->what & mask) { \ return true; \ } else { \ return false; \ @@ -272,203 +296,144 @@ static bool _ocf_metadata_test_##what##_##type(struct ocf_cache *cache, \ } \ } \ \ -static bool _ocf_metadata_test_out_##what##_##type(struct ocf_cache *cache, \ - ocf_cache_line_t line, uint8_t start, uint8_t stop) \ +static inline bool _ocf_metadata_test_out_##what##_##type( \ + struct ocf_metadata_map *entry, \ + uint8_t start, uint8_t stop) \ { \ type mask = _get_mask_##type(start, stop); \ \ - struct ocf_metadata_ctrl *ctrl = \ - (struct ocf_metadata_ctrl *) cache->metadata.priv; \ -\ - struct ocf_metadata_raw *raw = \ - &ctrl->raw_desc[metadata_segment_collision]; \ -\ - const struct ocf_metadata_map_##type *map = raw->mem_pool; \ + const struct ocf_metadata_map_##type *map = (const void *)entry; \ \ - _raw_bug_on(raw, line); \ -\ - if (map[line].what & ~mask) { \ + if (map->what & ~mask) { \ return true; \ } else { \ return false; \ } \ } \ \ -static bool _ocf_metadata_clear_##what##_##type(struct ocf_cache *cache, \ - ocf_cache_line_t line, uint8_t start, uint8_t stop) \ +static inline bool _ocf_metadata_clear_##what##_##type( \ + struct ocf_metadata_map *entry, \ + uint8_t start, uint8_t stop) \ { \ type mask = _get_mask_##type(start, stop); \ \ - struct ocf_metadata_ctrl *ctrl = \ - (struct ocf_metadata_ctrl *) cache->metadata.priv; \ -\ - struct ocf_metadata_raw *raw = \ - &ctrl->raw_desc[metadata_segment_collision]; \ -\ - struct ocf_metadata_map_##type *map = raw->mem_pool; \ + struct ocf_metadata_map_##type *map = (void *)entry; \ \ - _raw_bug_on(raw, line); \ + map->what &= ~mask; \ \ - map[line].what &= ~mask; \ -\ - if (map[line].what) { \ + if (map->what) { \ return true; \ } else { \ return false; \ } \ } \ \ -static bool _ocf_metadata_set_##what##_##type(struct ocf_cache *cache, \ - ocf_cache_line_t line, uint8_t start, uint8_t stop) \ +static inline bool _ocf_metadata_set_##what##_##type( \ + struct ocf_metadata_map *entry, \ + uint8_t start, uint8_t stop) \ { \ bool result; \ type mask = _get_mask_##type(start, stop); \ \ - struct ocf_metadata_ctrl *ctrl = \ - (struct ocf_metadata_ctrl *) cache->metadata.priv; \ -\ - struct ocf_metadata_raw *raw = \ - &ctrl->raw_desc[metadata_segment_collision]; \ -\ - struct ocf_metadata_map_##type *map = raw->mem_pool; \ -\ - _raw_bug_on(raw, line); \ + struct ocf_metadata_map_##type *map = (void *)entry; \ \ - result = map[line].what ? true : false; \ + result = map->what ? true : false; \ \ - map[line].what |= mask; \ + map->what |= mask; \ \ return result; \ } \ \ -static bool _ocf_metadata_test_and_set_##what##_##type( \ - struct ocf_cache *cache, ocf_cache_line_t line, \ +static inline bool _ocf_metadata_test_and_set_##what##_##type( \ + struct ocf_metadata_map *entry, \ uint8_t start, uint8_t stop, bool all) \ { \ bool test; \ type mask = _get_mask_##type(start, stop); \ \ - struct ocf_metadata_ctrl *ctrl = \ - (struct ocf_metadata_ctrl *) cache->metadata.priv; \ -\ - struct ocf_metadata_raw *raw = \ - &ctrl->raw_desc[metadata_segment_collision]; \ -\ - struct ocf_metadata_map_##type *map = raw->mem_pool; \ -\ - _raw_bug_on(raw, line); \ + struct ocf_metadata_map_##type *map = (void *)entry; \ \ if (all) { \ - if (mask == (map[line].what & mask)) { \ + if (mask == (map->what & mask)) { \ test = true; \ } else { \ test = false; \ } \ } else { \ - if (map[line].what & mask) { \ + if (map->what & mask) { \ test = true; \ } else { \ test = false; \ } \ } \ \ - map[line].what |= mask; \ + map->what |= mask; \ return test; \ } \ \ -static bool _ocf_metadata_test_and_clear_##what##_##type( \ - struct ocf_cache *cache, ocf_cache_line_t line, \ +static inline bool _ocf_metadata_test_and_clear_##what##_##type( \ + struct ocf_metadata_map *entry, \ uint8_t start, uint8_t stop, bool all) \ { \ bool test; \ type mask = _get_mask_##type(start, stop); \ \ - struct ocf_metadata_ctrl *ctrl = \ - (struct ocf_metadata_ctrl *) cache->metadata.priv; \ -\ - struct ocf_metadata_raw *raw = \ - &ctrl->raw_desc[metadata_segment_collision]; \ -\ - struct ocf_metadata_map_##type *map = raw->mem_pool; \ -\ - _raw_bug_on(raw, line); \ + struct ocf_metadata_map_##type *map = (void *)entry; \ \ if (all) { \ - if (mask == (map[line].what & mask)) { \ + if (mask == (map->what & mask)) { \ test = true; \ } else { \ test = false; \ } \ } else { \ - if (map[line].what & mask) { \ + if (map->what & mask) { \ test = true; \ } else { \ test = false; \ } \ } \ \ - map[line].what &= ~mask; \ + map->what &= ~mask; \ return test; \ } #define ocf_metadata_bit_func_basic(type) \ -static bool _ocf_metadata_clear_valid_if_clean_##type(struct ocf_cache *cache, \ - ocf_cache_line_t line, uint8_t start, uint8_t stop) \ +static inline bool _ocf_metadata_clear_valid_if_clean_##type( \ + struct ocf_metadata_map *entry, \ + uint8_t start, uint8_t stop) \ { \ type mask = _get_mask_##type(start, stop); \ \ - struct ocf_metadata_ctrl *ctrl = \ - (struct ocf_metadata_ctrl *) cache->metadata.priv; \ -\ - struct ocf_metadata_raw *raw = \ - &ctrl->raw_desc[metadata_segment_collision]; \ -\ - struct ocf_metadata_map_##type *map = raw->mem_pool; \ + struct ocf_metadata_map_##type *map = (void *)entry; \ \ - _raw_bug_on(raw, line); \ + map->valid &= (mask & map->dirty) | (~mask); \ \ - map[line].valid &= (mask & map[line].dirty) | (~mask); \ -\ - if (map[line].valid) { \ + if (map->valid) { \ return true; \ } else { \ return false; \ } \ } \ \ -static void _ocf_metadata_clear_dirty_if_invalid_##type(struct ocf_cache *cache, \ - ocf_cache_line_t line, uint8_t start, uint8_t stop) \ +static inline void _ocf_metadata_clear_dirty_if_invalid_##type( \ + struct ocf_metadata_map *entry, \ + uint8_t start, uint8_t stop) \ { \ type mask = _get_mask_##type(start, stop); \ \ - struct ocf_metadata_ctrl *ctrl = \ - (struct ocf_metadata_ctrl *) cache->metadata.priv; \ -\ - struct ocf_metadata_raw *raw = \ - &ctrl->raw_desc[metadata_segment_collision]; \ -\ - struct ocf_metadata_map_##type *map = raw->mem_pool; \ + struct ocf_metadata_map_##type *map = (void *)entry; \ \ - _raw_bug_on(raw, line); \ -\ - map[line].dirty &= (mask & map[line].valid) | (~mask); \ + map->dirty &= (mask & map->valid) | (~mask); \ } \ \ /* true if no incorrect combination of status bits */ \ -static bool _ocf_metadata_check_##type(struct ocf_cache *cache, \ - ocf_cache_line_t line) \ +static inline bool _ocf_metadata_check_##type( \ + const struct ocf_metadata_map *entry) \ { \ - struct ocf_metadata_ctrl *ctrl = \ - (struct ocf_metadata_ctrl *) cache->metadata.priv; \ -\ - struct ocf_metadata_raw *raw = \ - &ctrl->raw_desc[metadata_segment_collision]; \ -\ - struct ocf_metadata_map_##type *map = raw->mem_pool; \ -\ - _raw_bug_on(raw, line); \ + const struct ocf_metadata_map_##type *map = (const void *)entry; \ \ - return (map[line].dirty & (~map[line].valid)) == 0; \ + return (map->dirty & (~map->valid)) == 0; \ } #ifdef OCF_BLOCK_SIZE_4K @@ -479,7 +444,6 @@ ocf_metadata_bit_func_basic_no_type() #endif #define ocf_metadata_bit_funcs(type) \ -ocf_metadata_bit_struct(type); \ ocf_metadata_bit_func(dirty, type); \ ocf_metadata_bit_func(valid, type); \ ocf_metadata_bit_func_basic(type) @@ -494,3 +458,95 @@ ocf_metadata_bit_funcs(u32); ocf_metadata_bit_funcs(u64); ocf_metadata_bit_funcs(u128); #endif + +/******************************************************************************* + * Status operations dispatched by cache line size + ******************************************************************************/ + +#ifdef OCF_BLOCK_SIZE_4K +#define _ocf_metadata_bit_dispatch(line_size, func, ...) \ + switch (line_size) { \ + case ocf_cache_line_size_4: \ + return func(__VA_ARGS__); \ + case ocf_cache_line_size_8: \ + case ocf_cache_line_size_16: \ + case ocf_cache_line_size_32: \ + return func##_u8(__VA_ARGS__); \ + case ocf_cache_line_size_64: \ + return func##_u16(__VA_ARGS__); \ + case ocf_cache_line_size_none: \ + default: \ + ENV_BUG(); \ + } +#else +#define _ocf_metadata_bit_dispatch(line_size, func, ...) \ + switch (line_size) { \ + case ocf_cache_line_size_4: \ + return func##_u8(__VA_ARGS__); \ + case ocf_cache_line_size_8: \ + return func##_u16(__VA_ARGS__); \ + case ocf_cache_line_size_16: \ + return func##_u32(__VA_ARGS__); \ + case ocf_cache_line_size_32: \ + return func##_u64(__VA_ARGS__); \ + case ocf_cache_line_size_64: \ + return func##_u128(__VA_ARGS__); \ + case ocf_cache_line_size_none: \ + default: \ + ENV_BUG(); \ + } +#endif + +#define _ocf_metadata_bit_funcs_5arg(what) \ +static inline bool ocf_metadata_bit_##what( \ + struct ocf_metadata_map *entry, \ + ocf_cache_line_size_t line_size, \ + uint8_t start, uint8_t stop, bool all) \ +{ \ + _ocf_metadata_bit_dispatch(line_size, _ocf_metadata_##what, \ + entry, start, stop, all); \ + return false; \ +} + +#define _ocf_metadata_bit_funcs_4arg(what) \ +static inline bool ocf_metadata_bit_##what( \ + struct ocf_metadata_map *entry, \ + ocf_cache_line_size_t line_size, \ + uint8_t start, uint8_t stop) \ +{ \ + _ocf_metadata_bit_dispatch(line_size, _ocf_metadata_##what, \ + entry, start, stop); \ + return false; \ +} + +#define _ocf_metadata_bit_funcs(what) \ + _ocf_metadata_bit_funcs_5arg(test_##what) \ + _ocf_metadata_bit_funcs_4arg(test_out_##what) \ + _ocf_metadata_bit_funcs_4arg(clear_##what) \ + _ocf_metadata_bit_funcs_4arg(set_##what) \ + _ocf_metadata_bit_funcs_5arg(test_and_set_##what) \ + _ocf_metadata_bit_funcs_5arg(test_and_clear_##what) + +_ocf_metadata_bit_funcs(dirty) +_ocf_metadata_bit_funcs(valid) + +_ocf_metadata_bit_funcs_4arg(clear_valid_if_clean) + +static inline void ocf_metadata_bit_clear_dirty_if_invalid( + struct ocf_metadata_map *entry, ocf_cache_line_size_t line_size, + uint8_t start, uint8_t stop) +{ + _ocf_metadata_bit_dispatch(line_size, + _ocf_metadata_clear_dirty_if_invalid, + entry, start, stop); +} + +static inline bool ocf_metadata_bit_check( + const struct ocf_metadata_map *entry, + ocf_cache_line_size_t line_size) +{ + _ocf_metadata_bit_dispatch(line_size, _ocf_metadata_check, entry); + return false; +} + +#endif /* __METADATA_BIT_H__ */ diff --git a/src/metadata/metadata_collision.c b/src/metadata/metadata_collision.c index dbdfef1a..0e4cd187 100644 --- a/src/metadata/metadata_collision.c +++ b/src/metadata/metadata_collision.c @@ -90,6 +90,65 @@ void ocf_metadata_set_collision_prev(struct ocf_cache *cache, ocf_metadata_error(cache); } +/* + * Collision - Get + */ +struct ocf_metadata_map *ocf_metadata_get_collision(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_collision]), line); +} + +void ocf_metadata_get_core_info(struct ocf_cache *cache, + ocf_cache_line_t line, ocf_core_id_t *core_id, + uint64_t *core_line) +{ + const struct ocf_metadata_map *collision; + + collision = ocf_metadata_get_collision(cache, line); + + ENV_BUG_ON(!collision); + + if (core_id) + *core_id = collision->core_id; + if (core_line) + *core_line = collision->core_line; +} + +void ocf_metadata_set_core_info(struct ocf_cache *cache, + ocf_cache_line_t line, ocf_core_id_t core_id, + uint64_t core_line) +{ + struct ocf_metadata_map *collision; + + collision = ocf_metadata_get_collision(cache, line); + + if (collision) { + collision->core_id = core_id; + collision->core_line = core_line; + } else { + ocf_metadata_error(cache); + } +} + +ocf_core_id_t ocf_metadata_get_core_id(struct ocf_cache *cache, + ocf_cache_line_t line) +{ + const struct ocf_metadata_map *collision; + + collision = ocf_metadata_get_collision(cache, line); + + if (collision) + return collision->core_id; + + ocf_metadata_error(cache); + return OCF_CORE_NUM; +} + void ocf_metadata_get_collision_info(struct ocf_cache *cache, ocf_cache_line_t line, ocf_cache_line_t *next, ocf_cache_line_t *prev) diff --git a/src/metadata/metadata_collision.h b/src/metadata/metadata_collision.h index 89a50ec2..53ac94c7 100644 --- a/src/metadata/metadata_collision.h +++ b/src/metadata/metadata_collision.h @@ -79,6 +79,20 @@ void ocf_metadata_set_collision_prev( struct ocf_cache *cache, ocf_cache_line_t line, ocf_cache_line_t prev); +struct ocf_metadata_map *ocf_metadata_get_collision( + struct ocf_cache *cache, ocf_cache_line_t line); + +void ocf_metadata_get_core_info(struct ocf_cache *cache, + ocf_cache_line_t line, ocf_core_id_t *core_id, + uint64_t *core_line); + +void ocf_metadata_set_core_info(struct ocf_cache *cache, + ocf_cache_line_t line, ocf_core_id_t core_id, + uint64_t core_line); + +ocf_core_id_t ocf_metadata_get_core_id( + struct ocf_cache *cache, ocf_cache_line_t line); + void ocf_metadata_get_collision_info( struct ocf_cache *cache, ocf_cache_line_t line, ocf_cache_line_t *next, ocf_cache_line_t *prev); diff --git a/src/metadata/metadata_core.c b/src/metadata/metadata_core.c index 795f3c3b..600b2f71 100644 --- a/src/metadata/metadata_core.c +++ b/src/metadata/metadata_core.c @@ -11,61 +11,6 @@ #include "metadata_internal.h" #include "metadata_raw.h" -void ocf_metadata_get_core_info(struct ocf_cache *cache, - ocf_cache_line_t line, ocf_core_id_t *core_id, - uint64_t *core_line) -{ - const struct ocf_metadata_map *collision; - 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); - - ENV_BUG_ON(!collision); - - if (core_id) - *core_id = collision->core_id; - if (core_line) - *core_line = collision->core_line; -} - -void ocf_metadata_set_core_info(struct ocf_cache *cache, - ocf_cache_line_t line, ocf_core_id_t core_id, - uint64_t core_line) -{ - struct ocf_metadata_map *collision; - struct ocf_metadata_ctrl *ctrl = - (struct ocf_metadata_ctrl *) cache->metadata.priv; - - collision = ocf_metadata_raw_wr_access(cache, - &(ctrl->raw_desc[metadata_segment_collision]), line); - - if (collision) { - collision->core_id = core_id; - collision->core_line = core_line; - } else { - ocf_metadata_error(cache); - } -} - -ocf_core_id_t ocf_metadata_get_core_id(struct ocf_cache *cache, - ocf_cache_line_t line) -{ - const struct ocf_metadata_map *collision; - 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); - - if (collision) - return collision->core_id; - - ocf_metadata_error(cache); - return OCF_CORE_NUM; -} - struct ocf_metadata_uuid *ocf_metadata_get_core_uuid( struct ocf_cache *cache, ocf_core_id_t core_id) { diff --git a/src/metadata/metadata_core.h b/src/metadata/metadata_core.h index e57dea05..4757bae4 100644 --- a/src/metadata/metadata_core.h +++ b/src/metadata/metadata_core.h @@ -64,17 +64,6 @@ struct ocf_core_meta_runtime { } part_counters[OCF_USER_IO_CLASS_MAX]; }; -void ocf_metadata_get_core_info(struct ocf_cache *cache, - ocf_cache_line_t line, ocf_core_id_t *core_id, - uint64_t *core_line); - -void ocf_metadata_set_core_info(struct ocf_cache *cache, - ocf_cache_line_t line, ocf_core_id_t core_id, - uint64_t core_line); - -ocf_core_id_t ocf_metadata_get_core_id( - struct ocf_cache *cache, ocf_cache_line_t line); - struct ocf_metadata_uuid *ocf_metadata_get_core_uuid( struct ocf_cache *cache, ocf_core_id_t core_id); From 40628ddf1a182de0c2e6d6e0d94c6adb4fe5cf2e Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Mon, 5 Oct 2026 19:46:30 +0200 Subject: [PATCH 7/8] metadata: Isolate metadata layout Instantiate metadata layout abstraction and untangle it from the rest of metadata code. Signed-off-by: Robert Baldyga --- src/concurrency/ocf_pio_concurrency.c | 8 +- src/metadata/metadata.c | 403 +++--------------- src/metadata/metadata.h | 8 - src/metadata/metadata_internal.h | 6 +- src/metadata/metadata_layout.c | 333 +++++++++++++++ src/metadata/metadata_layout.h | 175 ++++++++ src/metadata/metadata_passive_update.c | 9 +- src/metadata/metadata_raw.c | 99 ++--- src/metadata/metadata_raw.h | 20 +- src/metadata/metadata_raw_dynamic.c | 64 ++- src/metadata/metadata_segment.c | 6 +- .../pyocf/c/helpers/metadata_helpers.c | 13 +- 12 files changed, 665 insertions(+), 479 deletions(-) create mode 100644 src/metadata/metadata_layout.c create mode 100644 src/metadata/metadata_layout.h diff --git a/src/concurrency/ocf_pio_concurrency.c b/src/concurrency/ocf_pio_concurrency.c index 9ed42e58..14ec48b7 100644 --- a/src/concurrency/ocf_pio_concurrency.c +++ b/src/concurrency/ocf_pio_concurrency.c @@ -1,6 +1,7 @@ /* * Copyright(c) 2021-2022 Intel Corporation * Copyright(c) 2022-2024 Huawei Technologies + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ @@ -225,10 +226,11 @@ int ocf_pio_concurrency_init(struct ocf_alock **self, ocf_cache_t cache) struct ocf_metadata_raw *raw = &(ctrl->raw_desc[update_segments[i]]); pio_ctx->segments[i].first_entry = pages_to_alloc; pio_ctx->segments[i].id = update_segments[i]; - pio_ctx->segments[i].begin = raw->ssd_pages_offset; - pio_ctx->segments[i].end = raw->ssd_pages_offset + raw->ssd_pages; + pio_ctx->segments[i].begin = raw->layout->offset; + pio_ctx->segments[i].end = raw->layout->offset + + raw->layout->pages; - pages_to_alloc += raw->ssd_pages; + pages_to_alloc += raw->layout->pages; } ret = ocf_alock_init_inplace(alock, pages_to_alloc, name, &ocf_pio_conc_cbs, cache); diff --git a/src/metadata/metadata.c b/src/metadata/metadata.c index f8772082..3ffecc3e 100644 --- a/src/metadata/metadata.c +++ b/src/metadata/metadata.c @@ -12,6 +12,7 @@ #include "metadata_collision.h" #include "metadata_segment_id.h" #include "metadata_internal.h" +#include "metadata_layout.h" #include "metadata_io.h" #include "metadata_raw.h" #include "metadata_segment.h" @@ -37,297 +38,37 @@ #define OCF_DEBUG_PARAM(cache, format, ...) #endif -#define OCF_METADATA_HASH_DIFF_MAX 1000 - -/* - * get entries for specified metadata hash type - */ -static ocf_cache_line_t ocf_metadata_get_entries( - enum ocf_metadata_segment_id type, - ocf_cache_line_t cache_lines) -{ - ENV_BUG_ON(type >= metadata_segment_variable_size_start && cache_lines == 0); - - switch (type) { - case metadata_segment_collision: - case metadata_segment_cleaning: - case metadata_segment_lru: - case metadata_segment_list_info: - return cache_lines; - - case metadata_segment_hash: - return OCF_DIV_ROUND_UP(cache_lines, 4); - - case metadata_segment_sb_config: - return OCF_DIV_ROUND_UP(sizeof(struct ocf_superblock_config), - PAGE_SIZE); - - case metadata_segment_sb_runtime: - return OCF_DIV_ROUND_UP(sizeof(struct ocf_superblock_runtime), - PAGE_SIZE); - - case metadata_segment_reserved: - return 32; - - case metadata_segment_part_config: - return OCF_USER_IO_CLASS_MAX + 1; - - case metadata_segment_part_runtime: - return OCF_NUM_PARTITIONS; - - case metadata_segment_core_config: - return OCF_CORE_NUM; - - case metadata_segment_core_runtime: - return OCF_CORE_NUM; - - case metadata_segment_core_uuid: - return OCF_CORE_NUM; - - default: - break; - } - - ENV_BUG(); - return 0; -} - -/* - * Get size of particular hash metadata type element - */ -static int64_t ocf_metadata_get_element_size( - enum ocf_metadata_segment_id type, - ocf_cache_line_size_t line_size) -{ - int64_t size = 0; - - ENV_BUG_ON(type >= metadata_segment_variable_size_start && !line_size); - - switch (type) { - case metadata_segment_lru: - size = sizeof(struct ocf_lru_meta); - break; - - case metadata_segment_cleaning: - size = sizeof(struct cleaning_policy_meta); - break; - - case metadata_segment_collision: - size = sizeof(struct ocf_metadata_map) - + ocf_metadata_status_sizeof(line_size); - break; - - case metadata_segment_list_info: - size = sizeof(struct ocf_metadata_list_info); - break; - - case metadata_segment_sb_config: - size = PAGE_SIZE; - break; - - case metadata_segment_sb_runtime: - size = PAGE_SIZE; - break; - - case metadata_segment_reserved: - size = PAGE_SIZE; - break; - - case metadata_segment_part_config: - size = sizeof(struct ocf_user_part_config); - break; - - case metadata_segment_part_runtime: - size = sizeof(struct ocf_part_runtime); - break; - - case metadata_segment_hash: - size = sizeof(struct ocf_hash_entry); - break; - - case metadata_segment_core_config: - size = sizeof(struct ocf_core_meta_config); - break; - - case metadata_segment_core_runtime: - size = sizeof(struct ocf_core_meta_runtime); - break; - - case metadata_segment_core_uuid: - size = sizeof(struct ocf_metadata_uuid); - break; - - default: - break; - - } - - ENV_BUG_ON(size > PAGE_SIZE); - - return size; -} - -/* - * Check if particular metadata type supports flapping - */ -static bool ocf_metadata_is_flapped( - enum ocf_metadata_segment_id type) -{ - switch (type) { - case metadata_segment_part_config: - case metadata_segment_core_config: - case metadata_segment_core_uuid: - return true; - - case metadata_segment_sb_config: - case metadata_segment_sb_runtime: - case metadata_segment_reserved: - case metadata_segment_part_runtime: - case metadata_segment_core_runtime: - case metadata_segment_cleaning: - case metadata_segment_lru: - case metadata_segment_collision: - case metadata_segment_list_info: - case metadata_segment_hash: - default: - return false; - - } -} - /* - * Metadata calculation exception handling. - * - * @param unused_lines - Unused pages - * @param device_lines - SSD Cache device pages amount - * - * @return true - Accept unused sapce - * @return false - unused space is not acceptable + * Calculate amount of cache lines taking into account required space for + * metadata and set up variable size RAW containers accordingly */ -static bool ocf_metadata_calculate_exception_hndl(ocf_cache_t cache, - int64_t unused_lines, int64_t device_lines) +static int ocf_metadata_calculate_variable_layout(struct ocf_cache *cache, + struct ocf_metadata_ctrl *ctrl, ocf_cache_line_size_t line_size, + bool cleaner_disabled) { static bool warn; - int64_t utilization = 0; + bool inexact; + int result; + + result = ocf_metadata_layout_fit(&ctrl->metadata_layout, line_size, + ctrl->device_lines, cleaner_disabled, &inexact); - if (!warn) { + if (inexact && !warn) { ocf_cache_log(cache, log_warn, "Metadata size calculation problem\n"); warn = true; } - if (unused_lines < 0) - return false; - - /* - * Accepted disk utilization is 90 % off SSD space - */ - utilization = (device_lines - unused_lines) * 100 / device_lines; - - if (utilization < 90) - return false; - - return true; -} - -/* - * Algorithm to calculate amount of cache lines taking into account required - * space for metadata - */ -static int ocf_metadata_calculate_metadata_size( - struct ocf_cache *cache, - struct ocf_metadata_ctrl *ctrl, - ocf_cache_line_size_t line_size) -{ - int64_t i_diff = 0, diff_lines = 0, cache_lines = ctrl->device_lines; - int64_t lowest_diff; - ocf_cache_line_t count_pages; - uint32_t i; - - OCF_DEBUG_PARAM(cache, "Cache lines = %lld", cache_lines); - - lowest_diff = cache_lines; - - do { - count_pages = 0; - for (i = metadata_segment_variable_size_start; - i < metadata_segment_max; i++) { - struct ocf_metadata_raw *raw = &ctrl->raw_desc[i]; - - if (raw->disabled) - continue; - - /* Setup number of entries */ - raw->entries - = ocf_metadata_get_entries(i, cache_lines); - - /* - * Setup SSD location and size - */ - raw->ssd_pages_offset = ctrl->count_pages_fixed + count_pages; - raw->ssd_pages = OCF_DIV_ROUND_UP(raw->entries, - raw->entries_in_page); - - /* Update offset for next container */ - count_pages += ocf_metadata_raw_size_on_ssd(raw); - } - - /* - * Check if max allowed iteration exceeded - */ - if (i_diff >= OCF_METADATA_HASH_DIFF_MAX) { - /* - * Never should be here but try handle this exception - */ - if (ocf_metadata_calculate_exception_hndl(cache, - diff_lines, ctrl->device_lines)) { - break; - } - - if (i_diff > (2 * OCF_METADATA_HASH_DIFF_MAX)) { - /* - * We tried, but we fallen, have to return error - */ - ocf_cache_log(cache, log_err, - "Metadata size calculation ERROR\n"); - return -1; - } - } - - /* Calculate diff of cache lines */ - - /* Cache size in bytes */ - diff_lines = ctrl->device_lines * line_size; - /* Sub metadata size which is in 4 kiB unit */ - diff_lines -= (int64_t)(ctrl->count_pages_fixed + count_pages) * PAGE_SIZE; - /* Convert back to cache lines */ - diff_lines /= line_size; - /* Calculate difference */ - diff_lines -= cache_lines; - - if (diff_lines > 0) { - if (diff_lines < lowest_diff) - lowest_diff = diff_lines; - else if (diff_lines == lowest_diff) - break; - } - - /* Update new value of cache lines */ - cache_lines += diff_lines; - - OCF_DEBUG_PARAM(cache, "Diff pages = %lld", diff_lines); - OCF_DEBUG_PARAM(cache, "Cache lines = %lld", cache_lines); - - i_diff++; - - } while (diff_lines); + if (result == -OCF_ERR_INVAL) { + ocf_cache_log(cache, log_err, + "Metadata size calculation ERROR\n"); + } - ctrl->count_pages_variable = count_pages; - ctrl->cachelines = cache_lines; - OCF_DEBUG_PARAM(cache, "Cache lines = %u", ctrl->cachelines); + if (result) + return result; - if (ctrl->device_lines < ctrl->cachelines) - return -1; + OCF_DEBUG_PARAM(cache, "Cache lines = %u", + ctrl->metadata_layout.cachelines); return 0; } @@ -368,15 +109,15 @@ static void ocf_metadata_raw_info(struct ocf_cache *cache, OCF_DEBUG_PARAM(cache, " : raw type = %u", raw->raw_type); OCF_DEBUG_PARAM(cache, " : entry size = %u", - raw->entry_size); + raw->layout->entry_size); OCF_DEBUG_PARAM(cache, " : entries = %llu", - raw->entries); + raw->layout->entries); OCF_DEBUG_PARAM(cache, " : entries in page = %u", - raw->entries_in_page); + raw->layout->entries_in_page); OCF_DEBUG_PARAM(cache, " : page offset = %llu", - raw->ssd_pages_offset); + raw->layout->offset); OCF_DEBUG_PARAM(cache, " : pages = %llu", - raw->ssd_pages); + raw->layout->pages); } /* Provide capacity info */ @@ -425,7 +166,7 @@ void ocf_metadata_deinit_variable_size(struct ocf_cache *cache) i < metadata_segment_max; i++) { ocf_metadata_segment_destroy(cache, ctrl->segment[i]); } - ctrl->count_pages_variable = 0; + ctrl->metadata_layout.pages_variable = 0; } static inline void ocf_metadata_config_init(ocf_cache_t cache, size_t size) @@ -465,7 +206,6 @@ static struct ocf_metadata_ctrl *ocf_metadata_ctrl_init( bool metadata_volatile) { struct ocf_metadata_ctrl *ctrl = NULL; - uint32_t page = 0; uint32_t i = 0; ctrl = env_vzalloc(sizeof(*ctrl)); @@ -486,30 +226,14 @@ static struct ocf_metadata_ctrl *ocf_metadata_ctrl_init( } else if (i == metadata_segment_core_uuid) { raw->raw_type = metadata_raw_type_dynamic; } - - /* Entry size configuration */ - raw->entry_size - = ocf_metadata_get_element_size(i, 0); - raw->entries_in_page = PAGE_SIZE / raw->entry_size; - - /* Setup flapping support */ - raw->flapping = ocf_metadata_is_flapped(i); - - /* Setup number of entries */ - raw->entries = ocf_metadata_get_entries(i, 0); - - /* - * Setup SSD location and size - */ - raw->ssd_pages_offset = page; - raw->ssd_pages = OCF_DIV_ROUND_UP(raw->entries, - raw->entries_in_page); - - /* Update offset for next container */ - page += ocf_metadata_raw_size_on_ssd(raw); } - ctrl->count_pages_fixed = page; + for (i = 0; i < metadata_segment_max; i++) + ctrl->raw_desc[i].layout = &ctrl->metadata_layout.segment[i]; + + /* Setup layout of fixed size segments */ + ocf_metadata_layout_init_fixed_size(&ctrl->metadata_layout, + !metadata_volatile); return ctrl; } @@ -667,32 +391,22 @@ int ocf_metadata_init_variable_size(struct ocf_cache *cache, ocf_volume_is_atomic(&cache->device->volume)) { raw->raw_type = metadata_raw_type_atomic; } - - if (i == metadata_segment_cleaning && cleaner_disabled) { - raw->disabled = true; - continue; - } - - /* Entry size configuration */ - raw->entry_size - = ocf_metadata_get_element_size(i, line_size); - raw->entries_in_page = PAGE_SIZE / raw->entry_size; - - /* Setup flapping support */ - raw->flapping = ocf_metadata_is_flapped(i); } - if (0 != ocf_metadata_calculate_metadata_size(cache, ctrl, line_size)) { + if (0 != ocf_metadata_calculate_variable_layout(cache, ctrl, line_size, + cleaner_disabled)) { ocf_cache_log(cache, log_err, "Couldn't fit metadata structure " "on device. Please try bigger cache device.\n"); return -OCF_ERR_INVAL_CACHE_DEV; } OCF_DEBUG_PARAM(cache, "Metadata begin pages = %u", ctrl->start_page); - OCF_DEBUG_PARAM(cache, "Metadata count pages fixed = %u", ctrl->count_pages_fixed); - OCF_DEBUG_PARAM(cache, "Metadata count pages variable = %u", ctrl->count_pages_variable); + OCF_DEBUG_PARAM(cache, "Metadata count pages fixed = %u", + ctrl->metadata_layout.pages_fixed); + OCF_DEBUG_PARAM(cache, "Metadata count pages variable = %u", + ctrl->metadata_layout.pages_variable); OCF_DEBUG_PARAM(cache, "Metadata end pages = %u", ctrl->start_page - + ocf_metadata_get_pages_count(cache)); + + ocf_metadata_layout_pages(&ctrl->metadata_layout)); superblock = ctrl->segment[metadata_segment_sb_config]; @@ -703,7 +417,7 @@ int ocf_metadata_init_variable_size(struct ocf_cache *cache, i < metadata_segment_max; i++) { struct ocf_metadata_raw *raw = &ctrl->raw_desc[i]; - if (raw->disabled) + if (raw->layout->disabled) continue; if (i == metadata_segment_collision) { @@ -729,7 +443,7 @@ int ocf_metadata_init_variable_size(struct ocf_cache *cache, for (i = 0; i < metadata_segment_max; i++) { ocf_cache_log(cache, log_info, "%s offset : %llu kiB\n", ocf_metadata_segment_names[i], - ctrl->raw_desc[i].ssd_pages_offset + ctrl->raw_desc[i].layout->offset * PAGE_SIZE / KiB); if (i == metadata_segment_sb_config) { ocf_cache_log(cache, log_info, "%s size : %lu B\n", @@ -744,7 +458,7 @@ int ocf_metadata_init_variable_size(struct ocf_cache *cache, } else { ocf_cache_log(cache, log_info, "%s size : %llu kiB\n", ocf_metadata_segment_names[i], - ctrl->raw_desc[i].ssd_pages + ctrl->raw_desc[i].layout->pages * PAGE_SIZE / KiB); } } @@ -761,15 +475,17 @@ int ocf_metadata_init_variable_size(struct ocf_cache *cache, cache->device->runtime_meta = METADATA_MEM_POOL(ctrl, metadata_segment_sb_runtime); - cache->device->collision_table_entries = ctrl->cachelines; + cache->device->collision_table_entries = + ctrl->metadata_layout.cachelines; cache->device->hash_table_entries = - ctrl->raw_desc[metadata_segment_hash].entries; + ctrl->raw_desc[metadata_segment_hash].layout->entries; cache->device->metadata_offset = - ocf_metadata_get_pages_count(cache) * PAGE_SIZE; + ocf_metadata_layout_pages(&ctrl->metadata_layout) * + PAGE_SIZE; - cache->conf_meta->cachelines = ctrl->cachelines; + cache->conf_meta->cachelines = ctrl->metadata_layout.cachelines; cache->conf_meta->line_size = line_size; cache->conf_meta->cleaner_disabled = cleaner_disabled; @@ -782,9 +498,10 @@ int ocf_metadata_init_variable_size(struct ocf_cache *cache, cache->device->metadata_offset / KiB); result = ocf_metadata_concurrency_attached_init(&cache->metadata.lock, - cache, ctrl->raw_desc[metadata_segment_hash].entries, + cache, ctrl->raw_desc[metadata_segment_hash]. + layout->entries, (uint32_t)ctrl->raw_desc[metadata_segment_collision]. - ssd_pages); + layout->pages); if (result) { ocf_cache_log(cache, log_err, "Failed to initialize attached " "metadata concurrency\n"); @@ -923,20 +640,6 @@ void ocf_metadata_init_hash_table(ocf_pipeline_t pipeline, void *priv, ocf_parallelize_run(parallelize); } -/* - * Get count of pages that is dedicated for metadata - */ -uint32_t ocf_metadata_get_pages_count(struct ocf_cache *cache) -{ - struct ocf_metadata_ctrl *ctrl = NULL; - - OCF_DEBUG_TRACE(cache); - - ctrl = (struct ocf_metadata_ctrl *) cache->metadata.priv; - - return ctrl->count_pages_fixed + ctrl->count_pages_variable; -} - /* * Get amount of cache lines */ @@ -949,7 +652,7 @@ ocf_cache_line_t ocf_metadata_get_cachelines_count( ctrl = (struct ocf_metadata_ctrl *) cache->metadata.priv; - return ctrl->cachelines; + return ctrl->metadata_layout.cachelines; } size_t ocf_metadata_size_of(struct ocf_cache *cache) @@ -989,7 +692,7 @@ uint64_t ocf_metadata_get_reserved_lba( OCF_DEBUG_TRACE(cache); ctrl = (struct ocf_metadata_ctrl *) cache->metadata.priv; - return ctrl->raw_desc[metadata_segment_reserved].ssd_pages_offset * + return ctrl->raw_desc[metadata_segment_reserved].layout->offset * PAGE_SIZE; } diff --git a/src/metadata/metadata.h b/src/metadata/metadata.h index 0b3024d7..d27103ae 100644 --- a/src/metadata/metadata.h +++ b/src/metadata/metadata.h @@ -121,14 +121,6 @@ void ocf_metadata_error(struct ocf_cache *cache); ocf_cache_line_t ocf_metadata_get_cachelines_count(struct ocf_cache *cache); -/** - * @brief Get amount of pages required for metadata - * - * @param cache - Cache instance - * @return Pages required for store metadata on cache device - */ -uint32_t ocf_metadata_get_pages_count(struct ocf_cache *cache); - /** * @brief Flush metadata * diff --git a/src/metadata/metadata_internal.h b/src/metadata/metadata_internal.h index 5fbd6bca..736445cf 100644 --- a/src/metadata/metadata_internal.h +++ b/src/metadata/metadata_internal.h @@ -1,6 +1,7 @@ /* * Copyright(c) 2020-2021 Intel Corporation * Copyright(c) 2025 Huawei Technologies + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,6 +13,7 @@ #include "metadata_segment.h" #include "metadata_segment_id.h" #include "metadata_raw.h" +#include "metadata_layout.h" #define METADATA_MEM_POOL(ctrl, section) ctrl->raw_desc[section].mem_pool @@ -19,14 +21,12 @@ * Metadata control structure */ struct ocf_metadata_ctrl { - ocf_cache_line_t cachelines; ocf_cache_line_t start_page; - uint32_t count_pages_fixed; - uint32_t count_pages_variable; uint32_t device_lines; size_t mapping_size; struct ocf_metadata_raw raw_desc[metadata_segment_max]; struct ocf_metadata_segment *segment[metadata_segment_max]; + struct ocf_metadata_layout metadata_layout; }; struct ocf_metadata_context { diff --git a/src/metadata/metadata_layout.c b/src/metadata/metadata_layout.c new file mode 100644 index 00000000..f0abc741 --- /dev/null +++ b/src/metadata/metadata_layout.c @@ -0,0 +1,333 @@ +/* + * Copyright(c) 2012-2022 Intel Corporation + * Copyright(c) 2026 Unvertical + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "metadata_layout.h" +#include "metadata_bit.h" +#include "metadata_cleaning_policy.h" +#include "metadata_collision.h" +#include "metadata_core.h" +#include "metadata_lru.h" +#include "metadata_partition.h" +#include "metadata_superblock.h" + +#define OCF_METADATA_LAYOUT_ITER_MAX 1000 + +ocf_cache_line_t ocf_metadata_segment_layout_entries( + enum ocf_metadata_segment_id segment, + ocf_cache_line_t cachelines) +{ + ENV_BUG_ON(segment >= metadata_segment_variable_size_start && + cachelines == 0); + + switch (segment) { + case metadata_segment_collision: + case metadata_segment_cleaning: + case metadata_segment_lru: + case metadata_segment_list_info: + return cachelines; + + case metadata_segment_hash: + return OCF_DIV_ROUND_UP(cachelines, 4); + + case metadata_segment_sb_config: + return OCF_DIV_ROUND_UP(sizeof(struct ocf_superblock_config), + PAGE_SIZE); + + case metadata_segment_sb_runtime: + return OCF_DIV_ROUND_UP(sizeof(struct ocf_superblock_runtime), + PAGE_SIZE); + + case metadata_segment_reserved: + return 32; + + case metadata_segment_part_config: + return OCF_USER_IO_CLASS_MAX + 1; + + case metadata_segment_part_runtime: + return OCF_NUM_PARTITIONS; + + case metadata_segment_core_config: + return OCF_CORE_NUM; + + case metadata_segment_core_runtime: + return OCF_CORE_NUM; + + case metadata_segment_core_uuid: + return OCF_CORE_NUM; + + default: + break; + } + + ENV_BUG(); + return 0; +} + +uint32_t ocf_metadata_segment_layout_entry_size( + enum ocf_metadata_segment_id segment, + ocf_cache_line_size_t line_size) +{ + uint32_t size = 0; + + ENV_BUG_ON(segment >= metadata_segment_variable_size_start && + !line_size); + + switch (segment) { + case metadata_segment_lru: + size = sizeof(struct ocf_lru_meta); + break; + + case metadata_segment_cleaning: + size = sizeof(struct cleaning_policy_meta); + break; + + case metadata_segment_collision: + size = sizeof(struct ocf_metadata_map) + + ocf_metadata_status_sizeof(line_size); + break; + + case metadata_segment_list_info: + size = sizeof(struct ocf_metadata_list_info); + break; + + case metadata_segment_sb_config: + size = PAGE_SIZE; + break; + + case metadata_segment_sb_runtime: + size = PAGE_SIZE; + break; + + case metadata_segment_reserved: + size = PAGE_SIZE; + break; + + case metadata_segment_part_config: + size = sizeof(struct ocf_user_part_config); + break; + + case metadata_segment_part_runtime: + size = sizeof(struct ocf_part_runtime); + break; + + case metadata_segment_hash: + size = sizeof(struct ocf_hash_entry); + break; + + case metadata_segment_core_config: + size = sizeof(struct ocf_core_meta_config); + break; + + case metadata_segment_core_runtime: + size = sizeof(struct ocf_core_meta_runtime); + break; + + case metadata_segment_core_uuid: + size = sizeof(struct ocf_metadata_uuid); + break; + + default: + break; + + } + + ENV_BUG_ON(size > PAGE_SIZE); + + return size; +} + +bool ocf_metadata_segment_layout_is_flapped( + enum ocf_metadata_segment_id segment) +{ + switch (segment) { + case metadata_segment_part_config: + case metadata_segment_core_config: + case metadata_segment_core_uuid: + return true; + + case metadata_segment_sb_config: + case metadata_segment_sb_runtime: + case metadata_segment_reserved: + case metadata_segment_part_runtime: + case metadata_segment_core_runtime: + case metadata_segment_cleaning: + case metadata_segment_lru: + case metadata_segment_collision: + case metadata_segment_list_info: + case metadata_segment_hash: + default: + return false; + + } +} + +/* + * Set up segment with given number of entries at given offset + * + * @return Number of pages occupied by segment on disk + */ +static uint32_t ocf_metadata_layout_setup_segment( + struct ocf_metadata_layout *layout, + enum ocf_metadata_segment_id id, + ocf_cache_line_size_t line_size, + ocf_cache_line_t entries, uint32_t offset) +{ + struct ocf_metadata_segment_layout *segment = &layout->segment[id]; + + segment->disabled = false; + segment->entry_size = ocf_metadata_segment_layout_entry_size(id, + line_size); + segment->entries_in_page = PAGE_SIZE / segment->entry_size; + segment->flapping = ocf_metadata_segment_layout_is_flapped(id); + segment->entries = entries; + segment->offset = offset; + segment->pages = OCF_DIV_ROUND_UP(segment->entries, + segment->entries_in_page); + + if (!layout->on_disk) + return 0; + + return ocf_metadata_segment_layout_pages(segment); +} + +void ocf_metadata_layout_init_fixed_size( + struct ocf_metadata_layout *layout, bool on_disk) +{ + uint32_t page = 0; + uint32_t i; + + ENV_BUG_ON(env_memset(layout, sizeof(*layout), 0)); + + layout->on_disk = on_disk; + + for (i = 0; i < metadata_segment_fixed_size_max; i++) { + page += ocf_metadata_layout_setup_segment(layout, i, 0, + ocf_metadata_segment_layout_entries(i, 0), + page); + } + + layout->pages_fixed = page; +} + +void ocf_metadata_layout_set_cachelines(struct ocf_metadata_layout *layout, + ocf_cache_line_size_t line_size, ocf_cache_line_t cachelines, + bool cleaner_disabled) +{ + uint32_t page = 0; + uint32_t i; + + layout->line_size = line_size; + layout->cachelines = cachelines; + + for (i = metadata_segment_variable_size_start; + i < metadata_segment_max; i++) { + if (i == metadata_segment_cleaning && cleaner_disabled) { + ENV_BUG_ON(env_memset(&layout->segment[i], + sizeof(layout->segment[i]), 0)); + layout->segment[i].disabled = true; + continue; + } + + page += ocf_metadata_layout_setup_segment(layout, i, line_size, + ocf_metadata_segment_layout_entries(i, + cachelines), + layout->pages_fixed + page); + } + + layout->pages_variable = page; +} + +/* + * Accept inexact result only if at least 90% of device space is used + */ +static bool ocf_metadata_layout_accept_inexact(int64_t unused_lines, + int64_t device_lines) +{ + int64_t utilization = 0; + + if (unused_lines < 0) + return false; + + utilization = (device_lines - unused_lines) * 100 / device_lines; + + if (utilization < 90) + return false; + + return true; +} + +/* + * Algorithm to calculate amount of cache lines taking into account required + * space for metadata + */ +int ocf_metadata_layout_fit(struct ocf_metadata_layout *layout, + ocf_cache_line_size_t line_size, uint64_t device_lines, + bool cleaner_disabled, bool *inexact) +{ + int64_t i_diff = 0, diff_lines = 0, cache_lines = device_lines; + int64_t lowest_diff; + + *inexact = false; + + lowest_diff = cache_lines; + + do { + ocf_metadata_layout_set_cachelines(layout, line_size, + cache_lines, cleaner_disabled); + + /* + * Check if max allowed iteration exceeded + */ + if (i_diff >= OCF_METADATA_LAYOUT_ITER_MAX) { + /* + * Never should be here but try handle this exception + */ + *inexact = true; + + if (ocf_metadata_layout_accept_inexact(diff_lines, + device_lines)) { + break; + } + + if (i_diff > (2 * OCF_METADATA_LAYOUT_ITER_MAX)) { + /* + * We tried, but we fallen, have to return error + */ + return -OCF_ERR_INVAL; + } + } + + /* Calculate diff of cache lines */ + + /* Cache size in bytes */ + diff_lines = device_lines * line_size; + /* Sub metadata size which is in 4 kiB unit */ + diff_lines -= (int64_t)ocf_metadata_layout_pages(layout) * + PAGE_SIZE; + /* Convert back to cache lines */ + diff_lines /= line_size; + /* Calculate difference */ + diff_lines -= cache_lines; + + if (diff_lines > 0) { + if (diff_lines < lowest_diff) + lowest_diff = diff_lines; + else if (diff_lines == lowest_diff) + break; + } + + /* Update new value of cache lines */ + cache_lines += diff_lines; + + i_diff++; + + } while (diff_lines); + + if (device_lines < layout->cachelines) + return -OCF_ERR_INVAL_CACHE_DEV; + + return 0; +} diff --git a/src/metadata/metadata_layout.h b/src/metadata/metadata_layout.h new file mode 100644 index 00000000..fc5e1cb0 --- /dev/null +++ b/src/metadata/metadata_layout.h @@ -0,0 +1,175 @@ +/* + * Copyright(c) 2012-2022 Intel Corporation + * Copyright(c) 2026 Unvertical + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __METADATA_LAYOUT_H__ +#define __METADATA_LAYOUT_H__ + +#include "ocf/ocf.h" +#include "../ocf_def_priv.h" +#include "metadata_segment_id.h" + +/* + * On-disk metadata layout. + * + * Metadata segments are placed on cache device one after another, in order + * of enum ocf_metadata_segment_id, starting at page 0. Each segment consists + * of pages holding entries (entries never cross page boundary, remainder of + * page is unused), rounded up to OCF_METADATA_SEGMENT_ALIGNMENT. Segments + * that support flapping are stored twice (two consecutive copies). + * + * Fixed size segments do not depend on cache configuration. Size of + * variable size segments depends on cache line size and number of cache + * lines. Cleaning segment is not present when cleaner is disabled. + */ + +/** Alignment of each segment copy on disk */ +#define OCF_METADATA_SEGMENT_ALIGNMENT (128 * KiB) + +struct ocf_metadata_segment_layout { + uint32_t entry_size; + /*!< Size of single entry */ + + uint32_t entries_in_page; + /*!< Number of entries in one page */ + + uint64_t entries; + /*!< Number of entries */ + + uint64_t pages; + /*!< Number of pages holding entries (single copy) */ + + uint64_t offset; + /*!< First page of segment on disk */ + + bool flapping; + /*!< Segment is stored in two copies */ + + bool disabled; + /*!< Segment is not present */ +}; + +struct ocf_metadata_layout { + bool on_disk; + /*!< False if metadata is volatile (no space on disk) */ + + ocf_cache_line_size_t line_size; + /*!< Cache line size */ + + ocf_cache_line_t cachelines; + /*!< Number of cache lines */ + + uint32_t pages_fixed; + /*!< Pages occupied by fixed size segments */ + + uint32_t pages_variable; + /*!< Pages occupied by variable size segments */ + + struct ocf_metadata_segment_layout segment[metadata_segment_max]; +}; + +/** + * @brief Number of entries in metadata segment + */ +ocf_cache_line_t ocf_metadata_segment_layout_entries( + enum ocf_metadata_segment_id segment, + ocf_cache_line_t cachelines); + +/** + * @brief Size of single entry in metadata segment + */ +uint32_t ocf_metadata_segment_layout_entry_size( + enum ocf_metadata_segment_id segment, + ocf_cache_line_size_t line_size); + +/** + * @brief Check if metadata segment is stored in two copies + */ +bool ocf_metadata_segment_layout_is_flapped( + enum ocf_metadata_segment_id segment); + +static inline uint32_t _ocf_metadata_layout_aligned_pages(uint64_t pages) +{ + const uint32_t alignment = OCF_METADATA_SEGMENT_ALIGNMENT / PAGE_SIZE; + + return OCF_DIV_ROUND_UP(pages, alignment) * alignment; +} + +/** + * @brief Number of pages occupied by segment on disk (all copies included) + */ +static inline uint32_t ocf_metadata_segment_layout_pages( + const struct ocf_metadata_segment_layout *segment) +{ + return _ocf_metadata_layout_aligned_pages(segment->pages) * + (segment->flapping ? 2 : 1); +} + +/** + * @brief First page of given copy of segment on disk + * + * @param segment - Segment layout + * @param flapping_idx - Index of segment copy (0 if segment is not flapped) + */ +static inline uint64_t ocf_metadata_segment_layout_offset( + const struct ocf_metadata_segment_layout *segment, + unsigned flapping_idx) +{ + return segment->offset + + _ocf_metadata_layout_aligned_pages(segment->pages) * + flapping_idx; +} + +/** + * @brief Initialize layout of fixed size segments + * + * @param layout - Layout to be initialized + * @param on_disk - False if metadata is volatile + */ +void ocf_metadata_layout_init_fixed_size( + struct ocf_metadata_layout *layout, bool on_disk); + +/** + * @brief Set up layout of variable size segments for given number of + * cache lines + * + * @param layout - Layout with fixed size segments initialized + * @param line_size - Cache line size + * @param cachelines - Number of cache lines + * @param cleaner_disabled - True if cleaning segment is not present + */ +void ocf_metadata_layout_set_cachelines(struct ocf_metadata_layout *layout, + ocf_cache_line_size_t line_size, ocf_cache_line_t cachelines, + bool cleaner_disabled); + +/** + * @brief Find number of cache lines that fit on device together with + * metadata and set up layout of variable size segments accordingly + * + * @param layout - Layout with fixed size segments initialized + * @param line_size - Cache line size + * @param device_lines - Size of cache device in cache lines + * @param cleaner_disabled - True if cleaning segment is not present + * @param[out] inexact - Set to true if exact fit was not found and + * accepted result leaves some space unused + * + * @retval 0 Success + * @retval -OCF_ERR_INVAL Calculation did not converge + * @retval -OCF_ERR_INVAL_CACHE_DEV Metadata does not fit on device + */ +int ocf_metadata_layout_fit(struct ocf_metadata_layout *layout, + ocf_cache_line_size_t line_size, uint64_t device_lines, + bool cleaner_disabled, bool *inexact); + +/** + * @brief Total number of pages occupied by metadata on disk + */ +static inline uint32_t ocf_metadata_layout_pages( + const struct ocf_metadata_layout *layout) +{ + return layout->pages_fixed + layout->pages_variable; +} + +#endif /* __METADATA_LAYOUT_H__ */ diff --git a/src/metadata/metadata_passive_update.c b/src/metadata/metadata_passive_update.c index bfaeca67..7e6d1ad4 100644 --- a/src/metadata/metadata_passive_update.c +++ b/src/metadata/metadata_passive_update.c @@ -1,6 +1,7 @@ /* * Copyright(c) 2012-2022 Intel Corporation * Copyright(c) 2024-2025 Huawei Technologies + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ @@ -42,8 +43,8 @@ static int passive_io_resume(struct ocf_request *req) for (i = 0; i < ARRAY_SIZE(update_segments); i++) { enum ocf_metadata_segment_id seg = update_segments[i]; struct ocf_metadata_raw *raw = &(ctrl->raw_desc[seg]); - uint64_t raw_start_page = raw->ssd_pages_offset; - uint64_t raw_end_page = raw_start_page + raw->ssd_pages - 1; + uint64_t raw_start_page = raw->layout->offset; + uint64_t raw_end_page = raw_start_page + raw->layout->pages - 1; uint64_t overlap_start = OCF_MAX(io_start_page, raw_start_page); uint64_t overlap_end = OCF_MIN(io_end_page, raw_end_page); uint64_t overlap_start_data = overlap_start - io_start_page; @@ -76,6 +77,7 @@ static void passive_io_page_lock_acquired(struct ocf_request *req) int ocf_metadata_passive_update(struct ocf_request *master) { ocf_cache_t cache = master->cache; + struct ocf_metadata_ctrl *ctrl = cache->metadata.priv; uint64_t io_start_page = BYTES_TO_PAGES(master->addr); uint64_t io_end_page = io_start_page + BYTES_TO_PAGES(master->bytes); struct ocf_request *req; @@ -86,7 +88,8 @@ int ocf_metadata_passive_update(struct ocf_request *master) return 0; } - if (io_start_page >= ocf_metadata_get_pages_count(cache)) { + if (io_start_page >= + ocf_metadata_layout_pages(&ctrl->metadata_layout)) { master->complete(master, 0); return 0; } diff --git a/src/metadata/metadata_raw.c b/src/metadata/metadata_raw.c index 43a2c9be..9bfac1a7 100644 --- a/src/metadata/metadata_raw.c +++ b/src/metadata/metadata_raw.c @@ -1,12 +1,14 @@ /* * Copyright(c) 2012-2021 Intel Corporation * Copyright(c) 2024 Huawei Technologies + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ #include "metadata.h" #include "metadata_segment_id.h" #include "metadata_raw.h" +#include "metadata_layout.h" #include "metadata_io.h" #include "metadata_raw_atomic.h" #include "../ocf_def_priv.h" @@ -35,31 +37,16 @@ * Common RAW Implementation ******************************************************************************/ -static uint32_t _raw_ram_segment_size_on_ssd(struct ocf_metadata_raw *raw) -{ - const size_t alignment = 128 * KiB / PAGE_SIZE; - - return OCF_DIV_ROUND_UP(raw->ssd_pages, alignment) * alignment; -} - - -static uint32_t _raw_ram_segment_size_on_ssd_total(struct ocf_metadata_raw *raw) -{ - uint32_t size = _raw_ram_segment_size_on_ssd(raw) * - (raw->flapping ? 2 : 1); - - return size; -} - /* * Check if page is valid for specified RAW descriptor */ static bool _raw_ssd_page_is_valid(struct ocf_metadata_raw *raw, uint32_t page) { - uint32_t size = _raw_ram_segment_size_on_ssd_total(raw); + uint32_t offset = ocf_metadata_segment_layout_offset(raw->layout, 0); + uint32_t size = ocf_metadata_segment_layout_pages(raw->layout); - ENV_BUG_ON(page < raw->ssd_pages_offset); - ENV_BUG_ON(page >= (raw->ssd_pages_offset + size)); + ENV_BUG_ON(page < offset); + ENV_BUG_ON(page >= (offset + size)); return true; } @@ -68,25 +55,25 @@ static bool _raw_ssd_page_is_valid(struct ocf_metadata_raw *raw, uint32_t page) * RAW RAM Implementation ******************************************************************************/ #define _RAW_RAM_ADDR(raw, line) \ - (raw->mem_pool + (((uint64_t)raw->entry_size * (line)))) + (raw->mem_pool + (((uint64_t)raw->layout->entry_size * (line)))) #define _RAW_RAM_PAGE(raw, line) \ - ((line) / raw->entries_in_page) + ((line) / raw->layout->entries_in_page) #define _RAW_RAM_PAGE_SSD(raw, line) \ - (raw->ssd_pages_offset + _RAW_RAM_PAGE(raw, line)) + (raw->layout->offset + _RAW_RAM_PAGE(raw, line)) #define _RAW_RAM_ADDR_PAGE(raw, line) \ (_RAW_RAM_ADDR(raw, \ - _RAW_RAM_PAGE(raw, line) * raw->entries_in_page)) + _RAW_RAM_PAGE(raw, line) * raw->layout->entries_in_page)) #define _RAW_RAM_GET(raw, line, data) \ - env_memcpy(data, raw->entry_size, _RAW_RAM_ADDR(raw, (line)), \ - raw->entry_size) + env_memcpy(data, raw->layout->entry_size, \ + _RAW_RAM_ADDR(raw, (line)), raw->layout->entry_size) #define _RAW_RAM_SET(raw, line, data) \ - env_memcpy(_RAW_RAM_ADDR(raw, line), raw->entry_size, \ - data, raw->entry_size) + env_memcpy(_RAW_RAM_ADDR(raw, line), raw->layout->entry_size, \ + data, raw->layout->entry_size) @@ -124,13 +111,13 @@ static int _raw_ram_init(ocf_cache_t cache, /* TODO: caller should specify explicitly whether to init mio conc? */ if (lock_page_pfn) { ret = ocf_mio_concurrency_init(&raw->mio_conc, - raw->ssd_pages_offset, raw->ssd_pages, cache); + raw->layout->offset, raw->layout->pages, cache); if (ret) return ret; } /* Allocate memory pool for entries */ - mem_pool_size = raw->ssd_pages; + mem_pool_size = raw->layout->pages; mem_pool_size *= PAGE_SIZE; raw->mem_pool_limit = mem_pool_size; raw->mem_pool = env_secure_alloc(mem_pool_size); @@ -153,7 +140,7 @@ static size_t _raw_ram_size_of(ocf_cache_t cache, struct ocf_metadata_raw *raw) { size_t size; - size = raw->ssd_pages; + size = raw->layout->pages; size *= PAGE_SIZE; return size; @@ -164,9 +151,7 @@ static size_t _raw_ram_size_of(ocf_cache_t cache, struct ocf_metadata_raw *raw) */ static uint32_t _raw_ram_size_on_ssd(struct ocf_metadata_raw *raw) { - size_t flapping_factor = raw->flapping ? 2 : 1; - - return _raw_ram_segment_size_on_ssd(raw) * flapping_factor; + return ocf_metadata_segment_layout_pages(raw->layout); } /* @@ -179,7 +164,7 @@ static uint32_t _raw_ram_checksum(ocf_cache_t cache, uint32_t step = 0; uint32_t crc = 0; - for (i = 0; i < raw->ssd_pages; i++) { + for (i = 0; i < raw->layout->pages; i++) { crc = env_crc32(crc, raw->mem_pool + PAGE_SIZE * i, PAGE_SIZE); OCF_COND_RESCHED(step, 10000); } @@ -192,7 +177,7 @@ static uint32_t _raw_ram_checksum(ocf_cache_t cache, */ static uint32_t _raw_ram_page(struct ocf_metadata_raw *raw, uint32_t entry) { - ENV_BUG_ON(entry >= raw->entries); + ENV_BUG_ON(entry >= raw->layout->entries); return _RAW_RAM_PAGE(raw, entry); } @@ -211,13 +196,13 @@ static void *_raw_ram_access(ocf_cache_t cache, static int _raw_ram_drain_page(ocf_cache_t cache, struct ocf_metadata_raw *raw, ctx_data_t *data, uint32_t page) { - uint32_t size = raw->entry_size * raw->entries_in_page; + uint32_t size = raw->layout->entry_size * raw->layout->entries_in_page; ocf_cache_line_t line; - ENV_BUG_ON(page > raw->ssd_pages); + ENV_BUG_ON(page > raw->layout->pages); ENV_BUG_ON(size > PAGE_SIZE); - line = page * raw->entries_in_page; + line = page * raw->layout->entries_in_page; OCF_DEBUG_PARAM(cache, "Line = %u, Page = %u", line, page); @@ -282,10 +267,10 @@ static void raw_ram_zero(ocf_cache_t cache, struct ocf_metadata_raw *raw, ctx->priv = priv; metadata_io_write_i_asynch(cache, cache->mngt_queue, ctx, - raw->ssd_pages_offset, - _raw_ram_segment_size_on_ssd_total(raw), - 0, raw_ram_zero_do_asynch_fill, - raw_ram_zero_end, NULL); + ocf_metadata_segment_layout_offset(raw->layout, 0), + ocf_metadata_segment_layout_pages(raw->layout), + 0, raw_ram_zero_do_asynch_fill, + raw_ram_zero_end, NULL); } struct _raw_ram_load_all_context { @@ -326,7 +311,8 @@ static void _raw_ram_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, struct _raw_ram_load_all_context *context; int result; - ENV_BUG_ON(raw->flapping ? flapping_idx > 1 : flapping_idx != 0); + ENV_BUG_ON(raw->layout->flapping ? + flapping_idx > 1 : flapping_idx != 0); OCF_DEBUG_TRACE(cache); context = env_vmalloc(sizeof(*context)); @@ -336,11 +322,11 @@ static void _raw_ram_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, context->raw = raw; context->cmpl = cmpl; context->priv = priv; - context->ssd_pages_offset = raw->ssd_pages_offset + - _raw_ram_segment_size_on_ssd(raw) * flapping_idx; + context->ssd_pages_offset = ocf_metadata_segment_layout_offset( + raw->layout, flapping_idx); result = metadata_io_read_i_asynch(cache, cache->mngt_queue, context, - context->ssd_pages_offset, raw->ssd_pages, 0, + context->ssd_pages_offset, raw->layout->pages, 0, _raw_ram_load_all_drain, _raw_ram_load_all_complete); if (result) _raw_ram_load_all_complete(cache, context, result); @@ -361,7 +347,7 @@ static int _raw_ram_flush_all_fill(ocf_cache_t cache, { struct _raw_ram_flush_all_context *context = priv; struct ocf_metadata_raw *raw = context->raw; - uint32_t size = raw->entry_size * raw->entries_in_page; + uint32_t size = raw->layout->entry_size * raw->layout->entries_in_page; ocf_cache_line_t line; uint32_t raw_page; @@ -369,7 +355,7 @@ static int _raw_ram_flush_all_fill(ocf_cache_t cache, ENV_BUG_ON(size > PAGE_SIZE); raw_page = page - context->ssd_pages_offset; - line = raw_page * raw->entries_in_page; + line = raw_page * raw->layout->entries_in_page; OCF_DEBUG_PARAM(cache, "Line = %u, Page = %u", line, raw_page); @@ -401,7 +387,8 @@ static void _raw_ram_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, { struct _raw_ram_flush_all_context *context; int result; - ENV_BUG_ON(raw->flapping ? flapping_idx > 1 : flapping_idx != 0); + ENV_BUG_ON(raw->layout->flapping ? + flapping_idx > 1 : flapping_idx != 0); OCF_DEBUG_TRACE(cache); context = env_vmalloc(sizeof(*context)); @@ -411,11 +398,11 @@ static void _raw_ram_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, context->raw = raw; context->cmpl = cmpl; context->priv = priv; - context->ssd_pages_offset = raw->ssd_pages_offset + - _raw_ram_segment_size_on_ssd(raw) * flapping_idx; + context->ssd_pages_offset = ocf_metadata_segment_layout_offset( + raw->layout, flapping_idx); result = metadata_io_write_i_asynch(cache, cache->mngt_queue, context, - context->ssd_pages_offset, raw->ssd_pages, 0, + context->ssd_pages_offset, raw->layout->pages, 0, _raw_ram_flush_all_fill, _raw_ram_flush_all_complete, raw->mio_conc); if (result) @@ -484,11 +471,11 @@ static int _raw_ram_flush_do_asynch_fill(ocf_cache_t cache, raw = ctx->raw; ENV_BUG_ON(!raw); - size = raw->entry_size * raw->entries_in_page; + size = raw->layout->entry_size * raw->layout->entries_in_page; ENV_BUG_ON(size > PAGE_SIZE); - raw_page = page - raw->ssd_pages_offset; - line = raw_page * raw->entries_in_page; + raw_page = page - raw->layout->offset; + line = raw_page * raw->layout->entries_in_page; OCF_DEBUG_PARAM(cache, "Line = %u, Page = %u", line, raw_page); @@ -619,7 +606,7 @@ static int _raw_ram_flush_do_asynch(ocf_cache_t cache, env_atomic_inc(&ctx->flush_req_cnt); result |= metadata_io_write_i_asynch(cache, req->io_queue, ctx, - raw->ssd_pages_offset + start_page, count, + raw->layout->offset + start_page, count, req->flags, _raw_ram_flush_do_asynch_fill, _raw_ram_flush_do_asynch_io_complete, diff --git a/src/metadata/metadata_raw.h b/src/metadata/metadata_raw.h index 723c5577..cdaa5cf7 100644 --- a/src/metadata/metadata_raw.h +++ b/src/metadata/metadata_raw.h @@ -1,5 +1,6 @@ /* * Copyright(c) 2012-2022 Intel Corporation + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,6 +8,7 @@ #define __METADATA_RAW_H__ #include "metadata_segment_id.h" +#include "metadata_layout.h" #include "../concurrency/ocf_mio_concurrency.h" /** @@ -63,21 +65,11 @@ struct ocf_metadata_raw { enum ocf_metadata_segment_id metadata_segment; /*!< Metadata segment */ enum ocf_metadata_raw_type raw_type; /*!< RAW implementation type */ - bool disabled; /*!< True if this raw container is disabled */ - - /** - * @name Metdata elements description - */ - uint32_t entry_size; /*!< Size of particular entry */ - uint32_t entries_in_page; /*!< Numbers of entries in one page*/ - uint64_t entries; /*!< Numbers of entries */ - bool flapping; /* !< Supports flapping */ - /** - * @name Location on cache device description + * @name Metadata elements description and location on cache device */ - uint64_t ssd_pages_offset; /*!< SSD (Cache device) Page offset */ - uint64_t ssd_pages; /*!< Numbers of pages that are required */ + const struct ocf_metadata_segment_layout *layout; + /*!< Segment layout */ const struct raw_iface *iface; /*!< RAW container interface*/ @@ -342,7 +334,7 @@ static inline bool _raw_is_valid(struct ocf_metadata_raw *raw, uint32_t entry) if (unlikely(!raw)) return false; - if (unlikely(entry >= raw->entries)) + if (unlikely(entry >= raw->layout->entries)) return false; return true; diff --git a/src/metadata/metadata_raw_dynamic.c b/src/metadata/metadata_raw_dynamic.c index 85b88065..ecba0135 100644 --- a/src/metadata/metadata_raw_dynamic.c +++ b/src/metadata/metadata_raw_dynamic.c @@ -1,6 +1,7 @@ /* * Copyright(c) 2012-2022 Intel Corporation * Copyright(c) 2024-2025 Huawei Technologies + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,6 +9,7 @@ #include "metadata_segment_id.h" #include "metadata_raw.h" #include "metadata_raw_dynamic.h" +#include "metadata_layout.h" #include "metadata_io.h" #include "../engine/cache_engine.h" #include "../engine/engine_common.h" @@ -38,20 +40,13 @@ * Check if page is valid for specified RAW descriptor */ -static uint32_t raw_dynamic_segment_size_on_ssd(struct ocf_metadata_raw *raw) -{ - const size_t alignment = 128 * KiB / PAGE_SIZE; - - return OCF_DIV_ROUND_UP(raw->ssd_pages, alignment) * alignment; -} - static bool _raw_ssd_page_is_valid(struct ocf_metadata_raw *raw, uint32_t page) { - uint32_t size = raw_dynamic_segment_size_on_ssd(raw) * - (raw->flapping ? 2 : 1); + uint32_t offset = ocf_metadata_segment_layout_offset(raw->layout, 0); + uint32_t size = ocf_metadata_segment_layout_pages(raw->layout); - ENV_BUG_ON(page < raw->ssd_pages_offset); - ENV_BUG_ON(page >= (raw->ssd_pages_offset + size)); + ENV_BUG_ON(page < offset); + ENV_BUG_ON(page >= (offset + size)); return true; } @@ -61,10 +56,11 @@ static bool _raw_ssd_page_is_valid(struct ocf_metadata_raw *raw, uint32_t page) ******************************************************************************/ #define _RAW_DYNAMIC_PAGE(raw, line) \ - ((line) / raw->entries_in_page) + ((line) / raw->layout->entries_in_page) #define _RAW_DYNAMIC_PAGE_OFFSET(raw, line) \ - ((line % raw->entries_in_page) * raw->entry_size) + ((line % raw->layout->entries_in_page) * \ + raw->layout->entry_size) /* * RAW DYNAMIC control structure @@ -140,7 +136,7 @@ int raw_dynamic_deinit(ocf_cache_t cache, ocf_mio_concurrency_deinit(&raw->mio_conc); - for (i = 0; i < raw->ssd_pages; i++) + for (i = 0; i < raw->layout->pages; i++) env_secure_free(ctrl->pages[i], PAGE_SIZE); env_mutex_destroy(&ctrl->lock); @@ -160,18 +156,19 @@ int raw_dynamic_init(ocf_cache_t cache, struct ocf_metadata_raw *raw) { struct _raw_ctrl *ctrl; - size_t size = sizeof(*ctrl) + (sizeof(ctrl->pages[0]) * raw->ssd_pages); + size_t size = sizeof(*ctrl) + + (sizeof(ctrl->pages[0]) * raw->layout->pages); int ret; OCF_DEBUG_TRACE(cache); - if (raw->entry_size > PAGE_SIZE) + if (raw->layout->entry_size > PAGE_SIZE) return -1; /* TODO: caller should specify explicitly whether to init mio conc? */ if (lock_page_pfn) { ret = ocf_mio_concurrency_init(&raw->mio_conc, - raw->ssd_pages_offset, raw->ssd_pages, cache); + raw->layout->offset, raw->layout->pages, cache); if (ret) return ret; } @@ -211,7 +208,7 @@ size_t raw_dynamic_size_of(ocf_cache_t cache, size *= PAGE_SIZE; /* Size of control structure */ - size += sizeof(*ctrl) + (sizeof(ctrl->pages[0]) * raw->ssd_pages); + size += sizeof(*ctrl) + (sizeof(ctrl->pages[0]) * raw->layout->pages); OCF_DEBUG_PARAM(cache, "Count = %d, Size = %lu", env_atomic_read(&ctrl->count), size); @@ -224,9 +221,7 @@ size_t raw_dynamic_size_of(ocf_cache_t cache, */ uint32_t raw_dynamic_size_on_ssd(struct ocf_metadata_raw *raw) { - size_t flapping_factor = raw->flapping ? 2 : 1; - - return raw_dynamic_segment_size_on_ssd(raw) * flapping_factor; + return ocf_metadata_segment_layout_pages(raw->layout); } /* @@ -240,7 +235,7 @@ uint32_t raw_dynamic_checksum(ocf_cache_t cache, uint32_t step = 0; uint32_t crc = 0; - for (i = 0; i < raw->ssd_pages; i++) { + for (i = 0; i < raw->layout->pages; i++) { if (ctrl->pages[i]) crc = env_crc32(crc, ctrl->pages[i], PAGE_SIZE); OCF_COND_RESCHED(step, 10000); @@ -254,7 +249,7 @@ uint32_t raw_dynamic_checksum(ocf_cache_t cache, */ uint32_t raw_dynamic_page(struct ocf_metadata_raw *raw, uint32_t entry) { - ENV_BUG_ON(entry >= raw->entries); + ENV_BUG_ON(entry >= raw->layout->entries); return _RAW_DYNAMIC_PAGE(raw, entry); } @@ -396,11 +391,10 @@ static int raw_dynamic_load_all_read(struct ocf_request *req) uint64_t ssd_pages_offset; uint64_t count; - ssd_pages_offset = raw->ssd_pages_offset + - raw_dynamic_segment_size_on_ssd(raw) * - context->flapping_idx; + ssd_pages_offset = ocf_metadata_segment_layout_offset(raw->layout, + context->flapping_idx); - count = metadata_io_size(context->i_page, raw->ssd_pages); + count = metadata_io_size(context->i_page, raw->layout->pages); ocf_req_forward_cache_init(req, raw_dynamic_load_all_read_end); @@ -416,7 +410,7 @@ static int raw_dynamic_load_all_update(struct ocf_request *req) struct raw_dynamic_load_all_context *context = req->priv; struct ocf_metadata_raw *raw = context->raw; ocf_cache_t cache = context->cache; - uint64_t count = metadata_io_size(context->i_page, raw->ssd_pages); + uint64_t count = metadata_io_size(context->i_page, raw->layout->pages); int result = 0; /* Reset head of data buffer */ @@ -428,7 +422,7 @@ static int raw_dynamic_load_all_update(struct ocf_request *req) context->i_page += count; - if (result || context->i_page >= raw->ssd_pages) { + if (result || context->i_page >= raw->layout->pages) { raw_dynamic_load_all_complete(context, result); return 0; } @@ -447,7 +441,8 @@ void raw_dynamic_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, struct ocf_request *req; int result; - ENV_BUG_ON(raw->flapping ? flapping_idx > 1 : flapping_idx != 0); + ENV_BUG_ON(raw->layout->flapping ? + flapping_idx > 1 : flapping_idx != 0); OCF_DEBUG_TRACE(cache); context = env_vzalloc(sizeof(*context)); @@ -555,7 +550,8 @@ void raw_dynamic_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, struct raw_dynamic_flush_all_context *context; int result; - ENV_BUG_ON(raw->flapping ? flapping_idx > 1 : flapping_idx != 0); + ENV_BUG_ON(raw->layout->flapping ? + flapping_idx > 1 : flapping_idx != 0); OCF_DEBUG_TRACE(cache); context = env_vmalloc(sizeof(*context)); @@ -565,11 +561,11 @@ void raw_dynamic_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, context->raw = raw; context->cmpl = cmpl; context->priv = priv; - context->ssd_pages_offset = raw->ssd_pages_offset + - raw_dynamic_segment_size_on_ssd(raw) * flapping_idx; + context->ssd_pages_offset = ocf_metadata_segment_layout_offset( + raw->layout, flapping_idx); result = metadata_io_write_i_asynch(cache, cache->mngt_queue, context, - context->ssd_pages_offset, raw->ssd_pages, 0, + context->ssd_pages_offset, raw->layout->pages, 0, raw_dynamic_flush_all_fill, raw_dynamic_flush_all_complete, raw->mio_conc); diff --git a/src/metadata/metadata_segment.c b/src/metadata/metadata_segment.c index 8a4599c4..be66d693 100644 --- a/src/metadata/metadata_segment.c +++ b/src/metadata/metadata_segment.c @@ -1,5 +1,6 @@ /* * Copyright(c) 2020-2021 Intel Corporation + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ #include "metadata_internal.h" @@ -118,7 +119,8 @@ void ocf_metadata_flush_segment(ocf_pipeline_t pipeline, ocf_metadata_superblock_get_next_flapping_idx( segment->superblock); - next_flapping_idx = segment->raw->flapping ? next_flapping_idx : 0; + next_flapping_idx = segment->raw->layout->flapping ? + next_flapping_idx : 0; ocf_metadata_raw_flush_all(cache, segment->raw, ocf_metadata_generic_complete, context, @@ -135,7 +137,7 @@ void ocf_metadata_load_segment(ocf_pipeline_t pipeline, unsigned flapping_idx = ocf_metadata_superblock_get_flapping_idx( segment->superblock); - flapping_idx = segment->raw->flapping ? flapping_idx : 0; + flapping_idx = segment->raw->layout->flapping ? flapping_idx : 0; ocf_metadata_raw_load_all(cache, segment->raw, ocf_metadata_generic_complete, context, flapping_idx); diff --git a/tests/functional/pyocf/c/helpers/metadata_helpers.c b/tests/functional/pyocf/c/helpers/metadata_helpers.c index aceb25cd..66670cba 100644 --- a/tests/functional/pyocf/c/helpers/metadata_helpers.c +++ b/tests/functional/pyocf/c/helpers/metadata_helpers.c @@ -1,5 +1,6 @@ /* * Copyright(c) 2022 Intel Corporation + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,7 +16,7 @@ uint64_t ocf_get_metadata_segment_start_page(ocf_cache_t cache, int segment) struct ocf_metadata_ctrl *ctrl = cache->metadata.priv; struct ocf_metadata_raw *raw = &ctrl->raw_desc[segment]; - return raw->ssd_pages_offset; + return raw->layout->offset; } uint64_t ocf_get_metadata_segment_page_count(ocf_cache_t cache, int segment) @@ -23,7 +24,7 @@ uint64_t ocf_get_metadata_segment_page_count(ocf_cache_t cache, int segment) struct ocf_metadata_ctrl *ctrl = cache->metadata.priv; struct ocf_metadata_raw *raw = &ctrl->raw_desc[segment]; - return raw->ssd_pages; + return raw->layout->pages; } uint64_t ocf_get_metadata_segment_elems_count(ocf_cache_t cache, int segment) @@ -31,7 +32,7 @@ uint64_t ocf_get_metadata_segment_elems_count(ocf_cache_t cache, int segment) struct ocf_metadata_ctrl *ctrl = cache->metadata.priv; struct ocf_metadata_raw *raw = &ctrl->raw_desc[segment]; - return raw->entries; + return raw->layout->entries; } uint64_t ocf_get_metadata_segment_elems_per_page(ocf_cache_t cache, int segment) @@ -39,7 +40,7 @@ uint64_t ocf_get_metadata_segment_elems_per_page(ocf_cache_t cache, int segment) struct ocf_metadata_ctrl *ctrl = cache->metadata.priv; struct ocf_metadata_raw *raw = &ctrl->raw_desc[segment]; - return raw->entries_in_page; + return raw->layout->entries_in_page; } uint64_t ocf_get_metadata_segment_elem_size(ocf_cache_t cache, int segment) @@ -50,7 +51,7 @@ uint64_t ocf_get_metadata_segment_elem_size(ocf_cache_t cache, int segment) if (segment == metadata_segment_sb_config) return offsetof(struct ocf_superblock_config, checksum); - return raw->entry_size; + return raw->layout->entry_size; } bool ocf_get_metadata_segment_is_flapped(ocf_cache_t cache, int segment) @@ -58,5 +59,5 @@ bool ocf_get_metadata_segment_is_flapped(ocf_cache_t cache, int segment) struct ocf_metadata_ctrl *ctrl = cache->metadata.priv; struct ocf_metadata_raw *raw = &ctrl->raw_desc[segment]; - return raw->flapping; + return raw->layout->flapping; } From a7b97f5f8a2741da037bc89dbc1606d6f50ed71a Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Mon, 5 Oct 2026 20:25:42 +0200 Subject: [PATCH 8/8] metadata: Remove unused fields from struct ocf_metadata_ctrl Signed-off-by: Robert Baldyga --- src/metadata/metadata.c | 20 +++++++------------- src/metadata/metadata_internal.h | 3 --- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/metadata/metadata.c b/src/metadata/metadata.c index 3ffecc3e..64d86252 100644 --- a/src/metadata/metadata.c +++ b/src/metadata/metadata.c @@ -43,15 +43,15 @@ * metadata and set up variable size RAW containers accordingly */ static int ocf_metadata_calculate_variable_layout(struct ocf_cache *cache, - struct ocf_metadata_ctrl *ctrl, ocf_cache_line_size_t line_size, - bool cleaner_disabled) + struct ocf_metadata_ctrl *ctrl, uint64_t device_lines, + ocf_cache_line_size_t line_size, bool cleaner_disabled) { static bool warn; bool inexact; int result; result = ocf_metadata_layout_fit(&ctrl->metadata_layout, line_size, - ctrl->device_lines, cleaner_disabled, &inexact); + device_lines, cleaner_disabled, &inexact); if (inexact && !warn) { ocf_cache_log(cache, log_warn, @@ -366,15 +366,10 @@ int ocf_metadata_init_variable_size(struct ocf_cache *cache, return -OCF_ERR_INVAL_CACHE_DEV; } - ctrl->device_lines = device_lines; - if (cache->metadata.line_size != line_size) /* Re-initialize metadata with different cache line size */ ocf_metadata_config_init(cache, line_size); - ctrl->mapping_size = ocf_metadata_status_sizeof(line_size) - + sizeof(struct ocf_metadata_map); - /* Initial setup of dynamic size RAW containers */ for (i = metadata_segment_variable_size_start; i < metadata_segment_max; i++) { @@ -393,20 +388,19 @@ int ocf_metadata_init_variable_size(struct ocf_cache *cache, } } - if (0 != ocf_metadata_calculate_variable_layout(cache, ctrl, line_size, - cleaner_disabled)) { + if (0 != ocf_metadata_calculate_variable_layout(cache, ctrl, + device_lines, line_size, cleaner_disabled)) { ocf_cache_log(cache, log_err, "Couldn't fit metadata structure " "on device. Please try bigger cache device.\n"); return -OCF_ERR_INVAL_CACHE_DEV; } - OCF_DEBUG_PARAM(cache, "Metadata begin pages = %u", ctrl->start_page); OCF_DEBUG_PARAM(cache, "Metadata count pages fixed = %u", ctrl->metadata_layout.pages_fixed); OCF_DEBUG_PARAM(cache, "Metadata count pages variable = %u", ctrl->metadata_layout.pages_variable); - OCF_DEBUG_PARAM(cache, "Metadata end pages = %u", ctrl->start_page - + ocf_metadata_layout_pages(&ctrl->metadata_layout)); + OCF_DEBUG_PARAM(cache, "Metadata end pages = %u", + ocf_metadata_layout_pages(&ctrl->metadata_layout)); superblock = ctrl->segment[metadata_segment_sb_config]; diff --git a/src/metadata/metadata_internal.h b/src/metadata/metadata_internal.h index 736445cf..9b4cbbcb 100644 --- a/src/metadata/metadata_internal.h +++ b/src/metadata/metadata_internal.h @@ -21,9 +21,6 @@ * Metadata control structure */ struct ocf_metadata_ctrl { - ocf_cache_line_t start_page; - uint32_t device_lines; - size_t mapping_size; struct ocf_metadata_raw raw_desc[metadata_segment_max]; struct ocf_metadata_segment *segment[metadata_segment_max]; struct ocf_metadata_layout metadata_layout;