lib/env_ocf: fix locks implementation

Some of the locks implementation in our OCF env
is different from suggested posix implementation (ocf/env/posix),
which leads to deadlocks in OCF v20.3

This patch copies correct implemention from example
posix env.

Change-Id: Ib3bb1cf3532b9e5ebc450a1569c620d95efe6704
Signed-off-by: Vitaliy Mysak <vitaliy.mysak@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1867
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Vitaliy Mysak 2020-04-15 16:31:15 +02:00 committed by Tomasz Zawadzki
parent 6ec892634e
commit e316ec90b2
2 changed files with 56 additions and 59 deletions

View File

@ -108,29 +108,6 @@ env_allocator_destroy(env_allocator *allocator)
free(allocator); free(allocator);
} }
} }
/* *** COMPLETION *** */
void
env_completion_init(env_completion *completion)
{
atomic_set(&completion->atom, 1);
}
void
env_completion_wait(env_completion *completion)
{
while (atomic_read(&completion->atom)) {
spdk_pause();
}
}
void
env_completion_complete(env_completion *completion)
{
atomic_set(&completion->atom, 0);
}
/* *** CRC *** */ /* *** CRC *** */
uint32_t uint32_t

View File

@ -234,7 +234,13 @@ typedef env_mutex env_rmutex;
static inline int env_rmutex_init(env_rmutex *rmutex) static inline int env_rmutex_init(env_rmutex *rmutex)
{ {
return env_mutex_init(rmutex); pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&rmutex->m, &attr);
return 0;
} }
static inline void env_rmutex_lock(env_rmutex *rmutex) static inline void env_rmutex_lock(env_rmutex *rmutex)
@ -485,84 +491,98 @@ static inline long env_atomic64_cmpxchg(env_atomic64 *a, long old, long new)
} }
/* *** COMPLETION *** */ /* *** COMPLETION *** */
struct completion { typedef struct completion {
env_atomic atom; sem_t sem;
}; } env_completion;
typedef struct completion env_completion; static inline void env_completion_init(env_completion *completion)
{
sem_init(&completion->sem, 0, 0);
}
void env_completion_init(env_completion *completion); static inline void env_completion_wait(env_completion *completion)
void env_completion_wait(env_completion *completion); {
void env_completion_complete(env_completion *completion); sem_wait(&completion->sem);
}
static inline void env_completion_complete(env_completion *completion)
{
sem_post(&completion->sem);
}
/* *** SPIN LOCKS *** */ /* *** SPIN LOCKS *** */
typedef env_mutex env_spinlock; typedef struct {
pthread_spinlock_t lock;
} env_spinlock;
static inline void env_spinlock_init(env_spinlock *l) static inline int env_spinlock_init(env_spinlock *l)
{ {
env_mutex_init(l); return pthread_spin_init(&l->lock, 0);
}
static inline int env_spinlock_trylock(env_spinlock *l)
{
return pthread_spin_trylock(&l->lock) ? -OCF_ERR_NO_LOCK : 0;
} }
static inline void env_spinlock_lock(env_spinlock *l) static inline void env_spinlock_lock(env_spinlock *l)
{ {
env_mutex_lock(l); ENV_BUG_ON(pthread_spin_lock(&l->lock));
} }
static inline void env_spinlock_unlock(env_spinlock *l) static inline void env_spinlock_unlock(env_spinlock *l)
{ {
env_mutex_unlock(l); ENV_BUG_ON(pthread_spin_unlock(&l->lock));
} }
static inline void env_spinlock_lock_irq(env_spinlock *l) #define env_spinlock_lock_irqsave(l, flags) \
{ (void)flags; \
env_spinlock_lock(l); env_spinlock_lock(l)
}
static inline void env_spinlock_unlock_irq(env_spinlock *l) #define env_spinlock_unlock_irqrestore(l, flags) \
{ (void)flags; \
env_spinlock_unlock(l); env_spinlock_unlock(l)
}
static inline void env_spinlock_lock_irqsave(env_spinlock *l, int flags) static inline void env_spinlock_destroy(env_spinlock *l)
{ {
env_spinlock_lock(l); ENV_BUG_ON(pthread_spin_destroy(&l->lock));
(void)flags;
}
static inline void env_spinlock_unlock_irqrestore(env_spinlock *l, int flags)
{
env_spinlock_unlock(l);
(void)flags;
} }
/* *** RW LOCKS *** */ /* *** RW LOCKS *** */
typedef env_rwsem env_rwlock; typedef struct {
pthread_rwlock_t lock;
} env_rwlock;
static inline void env_rwlock_init(env_rwlock *l) static inline void env_rwlock_init(env_rwlock *l)
{ {
env_rwsem_init(l); ENV_BUG_ON(pthread_rwlock_init(&l->lock, NULL));
} }
static inline void env_rwlock_read_lock(env_rwlock *l) static inline void env_rwlock_read_lock(env_rwlock *l)
{ {
env_rwsem_down_read(l); ENV_BUG_ON(pthread_rwlock_rdlock(&l->lock));
} }
static inline void env_rwlock_read_unlock(env_rwlock *l) static inline void env_rwlock_read_unlock(env_rwlock *l)
{ {
env_rwsem_up_read(l); ENV_BUG_ON(pthread_rwlock_unlock(&l->lock));
} }
static inline void env_rwlock_write_lock(env_rwlock *l) static inline void env_rwlock_write_lock(env_rwlock *l)
{ {
env_rwsem_down_write(l); ENV_BUG_ON(pthread_rwlock_wrlock(&l->lock));
} }
static inline void env_rwlock_write_unlock(env_rwlock *l) static inline void env_rwlock_write_unlock(env_rwlock *l)
{ {
env_rwsem_up_write(l); ENV_BUG_ON(pthread_rwlock_unlock(&l->lock));
}
static inline void env_rwlock_destroy(env_rwlock *l)
{
ENV_BUG_ON(pthread_rwlock_destroy(&l->lock));
} }
static inline void env_bit_set(int nr, volatile void *addr) static inline void env_bit_set(int nr, volatile void *addr)