Introduce hash bucket locks
There is one RW lock per hash bucket. Write lock is required to map cacheline, read lock is sufficient for traversing. Hash bucket locks are always acquired under global metadata read lock. This assures mutual exclusion with eviction and management paths, where global metadata write lock is held. Signed-off-by: Adam Rutkowski <adam.j.rutkowski@intel.com>
This commit is contained in:
@@ -10,125 +10,113 @@
|
||||
#define OCF_METADATA_RD 0
|
||||
#define OCF_METADATA_WR 1
|
||||
|
||||
void ocf_metadata_concurrency_init(struct ocf_cache *cache);
|
||||
void ocf_metadata_concurrency_init(struct ocf_metadata_lock *metadata_lock);
|
||||
|
||||
void ocf_metadata_concurrency_deinit(struct ocf_cache *cache);
|
||||
void ocf_metadata_concurrency_deinit(struct ocf_metadata_lock *metadata_lock);
|
||||
|
||||
int ocf_metadata_concurrency_attached_init(struct ocf_cache *cache);
|
||||
int ocf_metadata_concurrency_attached_init(
|
||||
struct ocf_metadata_lock *metadata_lock,
|
||||
uint64_t hash_table_entries);
|
||||
|
||||
static inline void ocf_metadata_eviction_lock(struct ocf_cache *cache)
|
||||
void ocf_metadata_concurrency_attached_deinit(
|
||||
struct ocf_metadata_lock *metadata_lock);
|
||||
|
||||
static inline void ocf_metadata_eviction_lock(
|
||||
struct ocf_metadata_lock *metadata_lock)
|
||||
{
|
||||
env_spinlock_lock(&cache->metadata.lock.eviction);
|
||||
env_spinlock_lock(&metadata_lock->eviction);
|
||||
}
|
||||
|
||||
static inline void ocf_metadata_eviction_unlock(struct ocf_cache *cache)
|
||||
static inline void ocf_metadata_eviction_unlock(
|
||||
struct ocf_metadata_lock *metadata_lock)
|
||||
{
|
||||
env_spinlock_unlock(&cache->metadata.lock.eviction);
|
||||
env_spinlock_unlock(&metadata_lock->eviction);
|
||||
}
|
||||
|
||||
#define OCF_METADATA_EVICTION_LOCK() \
|
||||
ocf_metadata_eviction_lock(cache)
|
||||
ocf_metadata_eviction_lock(&cache->metadata.lock)
|
||||
|
||||
#define OCF_METADATA_EVICTION_UNLOCK() \
|
||||
ocf_metadata_eviction_unlock(cache)
|
||||
ocf_metadata_eviction_unlock(&cache->metadata.lock)
|
||||
|
||||
static inline void ocf_metadata_lock(struct ocf_cache *cache, int rw)
|
||||
{
|
||||
if (rw == OCF_METADATA_WR)
|
||||
env_rwsem_down_write(&cache->metadata.lock.collision);
|
||||
else if (rw == OCF_METADATA_RD)
|
||||
env_rwsem_down_read(&cache->metadata.lock.collision);
|
||||
else
|
||||
ENV_BUG();
|
||||
}
|
||||
void ocf_metadata_start_exclusive_access(
|
||||
struct ocf_metadata_lock *metadata_lock);
|
||||
|
||||
int ocf_metadata_try_start_exclusive_access(
|
||||
struct ocf_metadata_lock *metadata_lock);
|
||||
|
||||
static inline void ocf_metadata_unlock(struct ocf_cache *cache, int rw)
|
||||
{
|
||||
if (rw == OCF_METADATA_WR)
|
||||
env_rwsem_up_write(&cache->metadata.lock.collision);
|
||||
else if (rw == OCF_METADATA_RD)
|
||||
env_rwsem_up_read(&cache->metadata.lock.collision);
|
||||
else
|
||||
ENV_BUG();
|
||||
}
|
||||
void ocf_metadata_end_exclusive_access(
|
||||
struct ocf_metadata_lock *metadata_lock);
|
||||
|
||||
static inline int ocf_metadata_try_lock(struct ocf_cache *cache, int rw)
|
||||
{
|
||||
int result = 0;
|
||||
int ocf_metadata_try_start_shared_access(
|
||||
struct ocf_metadata_lock *metadata_lock);
|
||||
|
||||
if (rw == OCF_METADATA_WR) {
|
||||
result = env_rwsem_down_write_trylock(
|
||||
&cache->metadata.lock.collision);
|
||||
} else if (rw == OCF_METADATA_RD) {
|
||||
result = env_rwsem_down_read_trylock(
|
||||
&cache->metadata.lock.collision);
|
||||
} else {
|
||||
ENV_BUG();
|
||||
}
|
||||
void ocf_metadata_start_shared_access(
|
||||
struct ocf_metadata_lock *metadata_lock);
|
||||
|
||||
if (result)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
void ocf_metadata_end_shared_access(
|
||||
struct ocf_metadata_lock *metadata_lock);
|
||||
|
||||
static inline void ocf_metadata_status_bits_lock(
|
||||
struct ocf_cache *cache, int rw)
|
||||
struct ocf_metadata_lock *metadata_lock, int rw)
|
||||
{
|
||||
if (rw == OCF_METADATA_WR)
|
||||
env_rwlock_write_lock(&cache->metadata.lock.status);
|
||||
env_rwlock_write_lock(&metadata_lock->status);
|
||||
else if (rw == OCF_METADATA_RD)
|
||||
env_rwlock_read_lock(&cache->metadata.lock.status);
|
||||
env_rwlock_read_lock(&metadata_lock->status);
|
||||
else
|
||||
ENV_BUG();
|
||||
}
|
||||
|
||||
static inline void ocf_metadata_status_bits_unlock(
|
||||
struct ocf_cache *cache, int rw)
|
||||
struct ocf_metadata_lock *metadata_lock, int rw)
|
||||
{
|
||||
if (rw == OCF_METADATA_WR)
|
||||
env_rwlock_write_unlock(&cache->metadata.lock.status);
|
||||
env_rwlock_write_unlock(&metadata_lock->status);
|
||||
else if (rw == OCF_METADATA_RD)
|
||||
env_rwlock_read_unlock(&cache->metadata.lock.status);
|
||||
env_rwlock_read_unlock(&metadata_lock->status);
|
||||
else
|
||||
ENV_BUG();
|
||||
}
|
||||
|
||||
#define OCF_METADATA_LOCK_RD() \
|
||||
ocf_metadata_lock(cache, OCF_METADATA_RD)
|
||||
#define OCF_METADATA_LOCK_RD() ocf_metadata_start_shared_access( \
|
||||
&cache->metadata.lock)
|
||||
|
||||
#define OCF_METADATA_UNLOCK_RD() \
|
||||
ocf_metadata_unlock(cache, OCF_METADATA_RD)
|
||||
#define OCF_METADATA_UNLOCK_RD() ocf_metadata_end_shared_access( \
|
||||
&cache->metadata.lock)
|
||||
|
||||
#define OCF_METADATA_LOCK_RD_TRY() \
|
||||
ocf_metadata_try_lock(cache, OCF_METADATA_RD)
|
||||
#define OCF_METADATA_LOCK_RD_TRY() ocf_metadata_try_start_shared_access( \
|
||||
&cache->metadata.lock)
|
||||
|
||||
#define OCF_METADATA_LOCK_WR() \
|
||||
ocf_metadata_lock(cache, OCF_METADATA_WR)
|
||||
#define OCF_METADATA_LOCK_WR() ocf_metadata_start_exclusive_access( \
|
||||
&cache->metadata.lock)
|
||||
|
||||
#define OCF_METADATA_LOCK_WR_TRY() \
|
||||
ocf_metadata_try_lock(cache, OCF_METADATA_WR)
|
||||
ocf_metadata_try_start_exclusive_access(&cache->metadata.lock)
|
||||
|
||||
#define OCF_METADATA_UNLOCK_WR() \
|
||||
ocf_metadata_unlock(cache, OCF_METADATA_WR)
|
||||
#define OCF_METADATA_UNLOCK_WR() ocf_metadata_end_exclusive_access( \
|
||||
&cache->metadata.lock)
|
||||
|
||||
#define OCF_METADATA_BITS_LOCK_RD() \
|
||||
ocf_metadata_status_bits_lock(cache, OCF_METADATA_RD)
|
||||
ocf_metadata_status_bits_lock(&cache->metadata.lock, \
|
||||
OCF_METADATA_RD)
|
||||
|
||||
#define OCF_METADATA_BITS_UNLOCK_RD() \
|
||||
ocf_metadata_status_bits_unlock(cache, OCF_METADATA_RD)
|
||||
ocf_metadata_status_bits_unlock(&cache->metadata.lock, \
|
||||
OCF_METADATA_RD)
|
||||
|
||||
#define OCF_METADATA_BITS_LOCK_WR() \
|
||||
ocf_metadata_status_bits_lock(cache, OCF_METADATA_WR)
|
||||
ocf_metadata_status_bits_lock(&cache->metadata.lock, \
|
||||
OCF_METADATA_WR)
|
||||
|
||||
#define OCF_METADATA_BITS_UNLOCK_WR() \
|
||||
ocf_metadata_status_bits_unlock(cache, OCF_METADATA_WR)
|
||||
ocf_metadata_status_bits_unlock(&cache->metadata.lock, \
|
||||
OCF_METADATA_WR)
|
||||
|
||||
#define OCF_METADATA_FLUSH_LOCK() \
|
||||
ocf_metadata_flush_lock(cache)
|
||||
|
||||
#define OCF_METADATA_FLUSH_UNLOCK() \
|
||||
ocf_metadata_flush_unlock(cache)
|
||||
void ocf_req_hash_lock_rd(struct ocf_request *req);
|
||||
void ocf_req_hash_unlock_rd(struct ocf_request *req);
|
||||
void ocf_req_hash_lock_wr(struct ocf_request *req);
|
||||
void ocf_req_hash_unlock_wr(struct ocf_request *req);
|
||||
void ocf_req_hash_lock_upgrade(struct ocf_request *req);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user