From 93bda499c746db5fa62ecc58d4b14041c03f63b6 Mon Sep 17 00:00:00 2001 From: Adam Rutkowski Date: Fri, 8 Jan 2021 12:10:28 +0100 Subject: [PATCH 1/4] Add functions to lock specific hash bucket Signed-off-by: Adam Rutkowski --- src/concurrency/ocf_metadata_concurrency.c | 28 ++++++++++++++++++++++ src/concurrency/ocf_metadata_concurrency.h | 11 +++++++++ 2 files changed, 39 insertions(+) diff --git a/src/concurrency/ocf_metadata_concurrency.c b/src/concurrency/ocf_metadata_concurrency.c index a36d3b8..ef0a737 100644 --- a/src/concurrency/ocf_metadata_concurrency.c +++ b/src/concurrency/ocf_metadata_concurrency.c @@ -221,6 +221,34 @@ int ocf_metadata_hash_try_lock(struct ocf_metadata_lock *metadata_lock, return 0; } +void ocf_metadata_lock_hash_rd(struct ocf_metadata_lock *metadata_lock, + ocf_cache_line_t hash) +{ + ocf_metadata_start_shared_access(metadata_lock); + ocf_metadata_hash_lock(metadata_lock, hash, OCF_METADATA_RD); +} + +void ocf_metadata_unlock_hash_rd(struct ocf_metadata_lock *metadata_lock, + ocf_cache_line_t hash) +{ + ocf_metadata_hash_unlock(metadata_lock, hash, OCF_METADATA_RD); + ocf_metadata_end_shared_access(metadata_lock); +} + +void ocf_metadata_lock_hash_wr(struct ocf_metadata_lock *metadata_lock, + ocf_cache_line_t hash) +{ + ocf_metadata_start_shared_access(metadata_lock); + ocf_metadata_hash_lock(metadata_lock, hash, OCF_METADATA_WR); +} + +void ocf_metadata_unlock_hash_wr(struct ocf_metadata_lock *metadata_lock, + ocf_cache_line_t hash) +{ + ocf_metadata_hash_unlock(metadata_lock, hash, OCF_METADATA_WR); + ocf_metadata_end_shared_access(metadata_lock); +} + /* NOTE: attempt to acquire hash lock for multiple core lines may end up * in deadlock. In order to hash lock multiple core lines safely, use * ocf_req_hash_lock_* functions */ diff --git a/src/concurrency/ocf_metadata_concurrency.h b/src/concurrency/ocf_metadata_concurrency.h index 2ae5721..b981bca 100644 --- a/src/concurrency/ocf_metadata_concurrency.h +++ b/src/concurrency/ocf_metadata_concurrency.h @@ -136,6 +136,17 @@ static inline void ocf_metadata_status_bits_unlock( ocf_metadata_status_bits_unlock(&cache->metadata.lock, \ OCF_METADATA_WR) +/* lock/unlock single hash */ +void ocf_metadata_lock_hash_rd(struct ocf_metadata_lock *metadata_lock, + ocf_cache_line_t hash); +void ocf_metadata_unlock_hash_rd(struct ocf_metadata_lock *metadata_lock, + ocf_cache_line_t hash); +void ocf_metadata_lock_hash_wr(struct ocf_metadata_lock *metadata_lock, + ocf_cache_line_t hash); +void ocf_metadata_unlock_hash_wr(struct ocf_metadata_lock *metadata_lock, + ocf_cache_line_t hash); + +/* lock/unlock single hash provided core id and core line */ void ocf_metadata_hash_lock_rd(struct ocf_metadata_lock *metadata_lock, uint32_t core_id, uint64_t core_line); void ocf_metadata_hash_unlock_rd(struct ocf_metadata_lock *metadata_lock, From bd20d6119b3ac21ca7fd74e85dfd4815ea716a44 Mon Sep 17 00:00:00 2001 From: Adam Rutkowski Date: Fri, 8 Jan 2021 12:11:11 +0100 Subject: [PATCH 2/4] External linkage for function to sparse single cline Signed-off-by: Adam Rutkowski --- src/metadata/metadata_misc.c | 10 +++++----- src/metadata/metadata_misc.h | 3 +++ src/utils/utils_cache_line.c | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/metadata/metadata_misc.c b/src/metadata/metadata_misc.c index 710633a..78bfcfa 100644 --- a/src/metadata/metadata_misc.c +++ b/src/metadata/metadata_misc.c @@ -91,8 +91,8 @@ int ocf_metadata_actor(struct ocf_cache *cache, /* the caller must hold the relevant cache block concurrency reader lock * and the metadata lock */ -void ocf_metadata_sparse_cache_line(struct ocf_cache *cache, - uint32_t cache_line) +void ocf_metadata_remove_cache_line(struct ocf_cache *cache, + ocf_cache_line_t cache_line) { ocf_part_id_t partition_id = ocf_metadata_get_partition_id(cache, cache_line); @@ -104,8 +104,8 @@ void ocf_metadata_sparse_cache_line(struct ocf_cache *cache, ocf_freelist_put_cache_line(cache->freelist, cache_line); } -static void _ocf_metadata_sparse_cache_line(struct ocf_cache *cache, - uint32_t cache_line) +void ocf_metadata_sparse_cache_line(struct ocf_cache *cache, + ocf_cache_line_t cache_line) { ocf_metadata_start_collision_shared_access(cache, cache_line); @@ -127,5 +127,5 @@ int ocf_metadata_sparse_range(struct ocf_cache *cache, int core_id, uint64_t start_byte, uint64_t end_byte) { return ocf_metadata_actor(cache, PARTITION_INVALID, core_id, - start_byte, end_byte, _ocf_metadata_sparse_cache_line); + start_byte, end_byte, ocf_metadata_sparse_cache_line); } diff --git a/src/metadata/metadata_misc.h b/src/metadata/metadata_misc.h index f3cca12..5a60177 100644 --- a/src/metadata/metadata_misc.h +++ b/src/metadata/metadata_misc.h @@ -21,6 +21,9 @@ static inline ocf_cache_line_t ocf_metadata_hash_func(ocf_cache_t cache, % entries); } +void ocf_metadata_remove_cache_line(struct ocf_cache *cache, + ocf_cache_line_t cache_line); + void ocf_metadata_sparse_cache_line(struct ocf_cache *cache, ocf_cache_line_t cache_line); diff --git a/src/utils/utils_cache_line.c b/src/utils/utils_cache_line.c index 342500a..f489165 100644 --- a/src/utils/utils_cache_line.c +++ b/src/utils/utils_cache_line.c @@ -45,7 +45,7 @@ static void __set_cache_line_invalid(struct ocf_cache *cache, uint8_t start_bit, */ if (!is_valid && !ocf_cache_line_are_waiters(cache, line)) { ocf_purge_eviction_policy(cache, line); - ocf_metadata_sparse_cache_line(cache, line); + ocf_metadata_remove_cache_line(cache, line); } } From 6d962b38e993129b61dd373ec8c8e663b232f1c2 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Thu, 14 Jan 2021 23:48:08 -0500 Subject: [PATCH 3/4] API for cacheline write trylock Signed-off-by: Michal Mielewczyk --- src/concurrency/ocf_cache_line_concurrency.c | 14 ++++++++++++++ src/concurrency/ocf_cache_line_concurrency.h | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/concurrency/ocf_cache_line_concurrency.c b/src/concurrency/ocf_cache_line_concurrency.c index 465d76f..cbe0833 100644 --- a/src/concurrency/ocf_cache_line_concurrency.c +++ b/src/concurrency/ocf_cache_line_concurrency.c @@ -1157,3 +1157,17 @@ void ocf_cache_line_unlock_rd(struct ocf_cache *cache, ocf_cache_line_t line) __unlock_cache_line_rd(c, line); } +bool ocf_cache_line_try_lock_wr(struct ocf_cache *cache, ocf_cache_line_t line) +{ + struct ocf_cache_line_concurrency *c = cache->device->concurrency.cache_line; + return __lock_cache_line_wr(c, line, NULL, NULL, 0); +} + +void ocf_cache_line_unlock_wr(struct ocf_cache *cache, ocf_cache_line_t line) +{ + struct ocf_cache_line_concurrency *c = cache->device->concurrency.cache_line; + + OCF_DEBUG_RQ(cache, "Cache line = %u", line); + + __unlock_cache_line_wr(c, line); +} diff --git a/src/concurrency/ocf_cache_line_concurrency.h b/src/concurrency/ocf_cache_line_concurrency.h index c49a803..c42c170 100644 --- a/src/concurrency/ocf_cache_line_concurrency.h +++ b/src/concurrency/ocf_cache_line_concurrency.h @@ -161,4 +161,23 @@ void ocf_cache_line_unlock_rd(struct ocf_cache *cache, ocf_cache_line_t line); */ bool ocf_cache_line_try_lock_rd(struct ocf_cache *cache, ocf_cache_line_t line); +/** + * @brief Release cache line write lock + * + * @param cache - OCF cache instance + * @param line - Cache line to be unlocked + */ +void ocf_cache_line_unlock_wr(struct ocf_cache *cache, ocf_cache_line_t line); + +/** + * @brief Attempt to lock cache line for write + * + * @param cache - OCF cache instance + * @param line - Cache line to be checked for waiters + * + * @retval true - write lock successfully acquired + * @retval false - failed to acquire write lock + */ +bool ocf_cache_line_try_lock_wr(struct ocf_cache *cache, ocf_cache_line_t line); + #endif /* OCF_CONCURRENCY_H_ */ From f206c64ff6da47b5f9157c5072ac24d4842b08c1 Mon Sep 17 00:00:00 2001 From: Adam Rutkowski Date: Fri, 8 Jan 2021 12:11:54 +0100 Subject: [PATCH 4/4] Fine granularity lock in cache_mngt_core_deinit_attached_meta Signed-off-by: Adam Rutkowski Signed-off-by: Michal Mielewczyk --- src/mngt/ocf_mngt_common.c | 62 ++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/src/mngt/ocf_mngt_common.c b/src/mngt/ocf_mngt_common.c index 44e2c36..4c91309 100644 --- a/src/mngt/ocf_mngt_common.c +++ b/src/mngt/ocf_mngt_common.c @@ -54,41 +54,51 @@ void cache_mngt_core_remove_from_cleaning_pol(ocf_core_t core) /* Deinitialize core metadata in attached metadata */ void cache_mngt_core_deinit_attached_meta(ocf_core_t core) { - int retry = 1; - uint64_t core_size = 0; - ocf_cleaning_t clean_pol_type; ocf_cache_t cache = ocf_core_get_cache(core); ocf_core_id_t core_id = ocf_core_get_id(core); + ocf_core_id_t iter_core_id; + ocf_cache_line_t curr_cline, prev_cline; + uint32_t hash, num_hash = cache->device->hash_table_entries; - core_size = ocf_volume_get_length(&core->volume); - if (!core_size) - core_size = ~0ULL; + for (hash = 0; hash < num_hash;) { + prev_cline = cache->device->collision_table_entries; + ocf_metadata_lock_hash_wr(&cache->metadata.lock, hash); - ocf_metadata_start_exclusive_access(&cache->metadata.lock); + curr_cline = ocf_metadata_get_hash(cache, hash); + while (curr_cline != cache->device->collision_table_entries) { + ocf_metadata_get_core_info(cache, curr_cline, &iter_core_id, + NULL); - clean_pol_type = cache->conf_meta->cleaning_policy_type; - while (retry) { - retry = 0; - if (cleaning_policy_ops[clean_pol_type].purge_range) { - retry = cleaning_policy_ops[clean_pol_type].purge_range(cache, - core_id, 0, core_size); + if (iter_core_id != core_id) { + /* `prev_cline` is a pointer to last not sparsed cacheline in + * current hash */ + prev_cline = curr_cline; + curr_cline = ocf_metadata_get_collision_next(cache, curr_cline); + continue; + } + + if (!ocf_cache_line_try_lock_wr(cache, curr_cline)) + break; + + if (metadata_test_dirty(cache, curr_cline)) + ocf_purge_cleaning_policy(cache, curr_cline); + ocf_metadata_sparse_cache_line(cache, curr_cline); + + ocf_cache_line_unlock_wr(cache, curr_cline); + + if (prev_cline != cache->device->collision_table_entries) + curr_cline = ocf_metadata_get_collision_next(cache, prev_cline); + else + curr_cline = ocf_metadata_get_hash(cache, hash); } + ocf_metadata_unlock_hash_wr(&cache->metadata.lock, hash); - if (!retry) { - /* Remove from collision_table and Partition. Put in FREELIST */ - retry = ocf_metadata_sparse_range(cache, core_id, 0, - core_size); - } - - if (retry) { - ocf_metadata_end_exclusive_access(&cache->metadata.lock); + /* Check whether all the cachelines from the hash bucket were sparsed */ + if (curr_cline == cache->device->collision_table_entries) + hash++; + else env_msleep(100); - ocf_metadata_start_exclusive_access( - &cache->metadata.lock); - } } - - ocf_metadata_end_exclusive_access(&cache->metadata.lock); } /* Mark core as removed in metadata */