From 5e2847432223b6dc5bdb25a1f18a5217afdd8127 Mon Sep 17 00:00:00 2001 From: Adam Rutkowski Date: Mon, 23 Sep 2019 11:08:27 -0400 Subject: [PATCH] Adding partition locks Adding locks to assure partition list consistency. Partition lists is typically modified under cacheline or hash bucket lock. This is not sufficient synchronization as adding/removing cacheline from partition list affects neighbouring cachelines state as well. Signed-off-by: Adam Rutkowski --- src/concurrency/ocf_metadata_concurrency.c | 12 ++++++++++++ src/concurrency/ocf_metadata_concurrency.h | 14 ++++++++++++++ src/metadata/metadata_partition.c | 8 ++++++++ src/metadata/metadata_structs.h | 1 + 4 files changed, 35 insertions(+) diff --git a/src/concurrency/ocf_metadata_concurrency.c b/src/concurrency/ocf_metadata_concurrency.c index 058271b..59814b3 100644 --- a/src/concurrency/ocf_metadata_concurrency.c +++ b/src/concurrency/ocf_metadata_concurrency.c @@ -8,13 +8,25 @@ void ocf_metadata_concurrency_init(struct ocf_metadata_lock *metadata_lock) { + unsigned i; + env_spinlock_init(&metadata_lock->eviction); env_rwlock_init(&metadata_lock->status); env_rwsem_init(&metadata_lock->global); + + for (i = 0; i < OCF_IO_CLASS_MAX; i++) { + env_spinlock_init(&metadata_lock->partition[i]); + } } void ocf_metadata_concurrency_deinit(struct ocf_metadata_lock *metadata_lock) { + unsigned i; + + for (i = 0; i < OCF_IO_CLASS_MAX; i++) { + env_spinlock_destroy(&metadata_lock->partition[i]); + } + env_spinlock_destroy(&metadata_lock->eviction); env_rwlock_destroy(&metadata_lock->status); env_rwsem_destroy(&metadata_lock->global); diff --git a/src/concurrency/ocf_metadata_concurrency.h b/src/concurrency/ocf_metadata_concurrency.h index ffef123..1445602 100644 --- a/src/concurrency/ocf_metadata_concurrency.h +++ b/src/concurrency/ocf_metadata_concurrency.h @@ -33,6 +33,20 @@ static inline void ocf_metadata_eviction_unlock( env_spinlock_unlock(&metadata_lock->eviction); } +static inline void ocf_metadata_partition_lock( + struct ocf_metadata_lock *metadata_lock, + ocf_part_id_t part_id) +{ + env_spinlock_lock(&metadata_lock->partition[part_id]); +} + +static inline void ocf_metadata_partition_unlock( + struct ocf_metadata_lock *metadata_lock, + ocf_part_id_t part_id) +{ + env_spinlock_unlock(&metadata_lock->partition[part_id]); +} + #define OCF_METADATA_EVICTION_LOCK() \ ocf_metadata_eviction_lock(&cache->metadata.lock) diff --git a/src/metadata/metadata_partition.c b/src/metadata/metadata_partition.c index b802101..437f400 100644 --- a/src/metadata/metadata_partition.c +++ b/src/metadata/metadata_partition.c @@ -26,6 +26,8 @@ void ocf_metadata_add_to_partition(struct ocf_cache *cache, ENV_BUG_ON(!(line < line_entries)); + ocf_metadata_partition_lock(&cache->metadata.lock, part_id); + /* First node to be added/ */ if (!part->runtime->curr_size) { @@ -55,6 +57,8 @@ void ocf_metadata_add_to_partition(struct ocf_cache *cache, } part->runtime->curr_size++; + + ocf_metadata_partition_unlock(&cache->metadata.lock, part_id); } /* Deletes the node with the given collision_index from the Partition list */ @@ -68,6 +72,8 @@ void ocf_metadata_remove_from_partition(struct ocf_cache *cache, ENV_BUG_ON(!(line < line_entries)); + ocf_metadata_partition_lock(&cache->metadata.lock, part_id); + /* Get Partition info */ ocf_metadata_get_partition_info(cache, line, NULL, &next_line, &prev_line); @@ -131,4 +137,6 @@ void ocf_metadata_remove_from_partition(struct ocf_cache *cache, } part->runtime->curr_size--; + + ocf_metadata_partition_unlock(&cache->metadata.lock, part_id); } diff --git a/src/metadata/metadata_structs.h b/src/metadata/metadata_structs.h index 9d6e681..71eb02a 100644 --- a/src/metadata/metadata_structs.h +++ b/src/metadata/metadata_structs.h @@ -441,6 +441,7 @@ struct ocf_metadata_lock env_spinlock eviction; /*!< Fast lock for eviction policy */ env_rwsem *hash; /*!< Hash bucket locks */ env_rwsem *collision_pages; /*!< Collision table page locks */ + env_spinlock partition[OCF_IO_CLASS_MAX]; /* partition lock */ uint32_t num_hash_entries; /*!< Hash bucket count */ uint32_t num_collision_pages; /*!< Collision table page count */ ocf_cache_t cache; /*!< Parent cache object */