diff --git a/src/metadata/metadata_collision.c b/src/metadata/metadata_collision.c index 7ef7ffd8..dbdfef1a 100644 --- a/src/metadata/metadata_collision.c +++ b/src/metadata/metadata_collision.c @@ -10,6 +10,37 @@ #include "metadata_internal.h" #include "../utils/utils_cache_line.h" +static inline void ocf_metadata_list_info_set( + struct ocf_metadata_list_info *info, + ocf_cache_line_t next, ocf_cache_line_t prev) +{ + struct ocf_metadata_list_info t = { }; + + t.next_col = next; + t.prev_col = prev; + info->entry = t.entry; +} + +static inline void ocf_metadata_list_info_set_next( + struct ocf_metadata_list_info *info, + ocf_cache_line_t next) +{ + struct ocf_metadata_list_info t = { .entry = info->entry }; + + t.next_col = next; + info->entry = t.entry; +} + +static inline void ocf_metadata_list_info_set_prev( + struct ocf_metadata_list_info *info, + ocf_cache_line_t prev) +{ + struct ocf_metadata_list_info t = { .entry = info->entry }; + + t.prev_col = prev; + info->entry = t.entry; +} + void ocf_metadata_set_collision_info(struct ocf_cache *cache, ocf_cache_line_t line, ocf_cache_line_t next, ocf_cache_line_t prev) @@ -21,12 +52,10 @@ void ocf_metadata_set_collision_info(struct ocf_cache *cache, info = ocf_metadata_raw_wr_access(cache, &(ctrl->raw_desc[metadata_segment_list_info]), line); - if (info) { - info->next_col = next; - info->prev_col = prev; - } else { + if (info) + ocf_metadata_list_info_set(info, next, prev); + else ocf_metadata_error(cache); - } } void ocf_metadata_set_collision_next(struct ocf_cache *cache, @@ -40,7 +69,7 @@ void ocf_metadata_set_collision_next(struct ocf_cache *cache, &(ctrl->raw_desc[metadata_segment_list_info]), line); if (info) - info->next_col = next; + ocf_metadata_list_info_set_next(info, next); else ocf_metadata_error(cache); } @@ -56,7 +85,7 @@ void ocf_metadata_set_collision_prev(struct ocf_cache *cache, &(ctrl->raw_desc[metadata_segment_list_info]), line); if (info) - info->prev_col = prev; + ocf_metadata_list_info_set_prev(info, prev); else ocf_metadata_error(cache); } @@ -74,10 +103,12 @@ void ocf_metadata_get_collision_info(struct ocf_cache *cache, info = ocf_metadata_raw_rd_access(cache, &(ctrl->raw_desc[metadata_segment_list_info]), line); if (info) { + /* Atomic read of the entry (aarch64/amd64) */ + struct ocf_metadata_list_info t = { .entry = info->entry }; if (next) - *next = info->next_col; + *next = t.next_col; if (prev) - *prev = info->prev_col; + *prev = t.prev_col; } else { ocf_metadata_error(cache); diff --git a/src/metadata/metadata_collision.h b/src/metadata/metadata_collision.h index f444c9b1..89a50ec2 100644 --- a/src/metadata/metadata_collision.h +++ b/src/metadata/metadata_collision.h @@ -15,13 +15,18 @@ */ struct ocf_metadata_list_info { - /* Previous cache line in collision list */ - ocf_cache_line_t prev_col : OCF_CACHE_LINE_BITS; - ocf_cache_line_t unused : 3; - /* Next cache line in collision list*/ - ocf_cache_line_t next_col : OCF_CACHE_LINE_BITS; - ocf_cache_line_t unused2 : 3; -} __attribute__((packed)); + union { + struct { + /* Previous cache line in collision list */ + ocf_cache_line_t prev_col : OCF_CACHE_LINE_BITS; + ocf_cache_line_t unused : 3; + /* Next cache line in collision list*/ + ocf_cache_line_t next_col : OCF_CACHE_LINE_BITS; + ocf_cache_line_t unused2 : 3; + } __attribute__((packed)); + uint64_t entry; + }; +}; /* Keep the struct ocf_metadata_list_info size of 8 bytes */ _Static_assert(sizeof(struct ocf_metadata_list_info) == sizeof(uint64_t),