Merge pull request #362 from robertbaldyga/fix-flush-deadlock

Fix deadlock on concurrent flush at the same cache
This commit is contained in:
Robert Baldyga 2020-04-05 10:49:41 +02:00 committed by GitHub
commit 72f11d0771
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 25 additions and 9 deletions

5
env/posix/ocf_env.h vendored
View File

@ -226,6 +226,11 @@ static inline void env_mutex_lock(env_mutex *mutex)
ENV_BUG_ON(pthread_mutex_lock(&mutex->m));
}
static inline int env_mutex_trylock(env_mutex *mutex)
{
return pthread_mutex_trylock(&mutex->m);
}
static inline int env_mutex_lock_interruptible(env_mutex *mutex)
{
env_mutex_lock(mutex);

View File

@ -102,6 +102,9 @@ typedef enum {
/** Flushing of core interrupted */
OCF_ERR_FLUSHING_INTERRUPTED,
/** Another flushing operation in progress */
OCF_ERR_FLUSH_IN_PROGRESS,
/** Adding core to core pool failed */
OCF_ERR_CANNOT_ADD_CORE_TO_POOL,

View File

@ -47,6 +47,11 @@ struct ocf_mngt_cache_flush_context
/* target core */
ocf_core_t core;
struct {
bool lock : 1;
bool freeze : 1;
} flags;
/* management operation identifier */
enum {
flush_cache = 0,
@ -87,24 +92,22 @@ static void _ocf_mngt_begin_flush(ocf_pipeline_t pipeline, void *priv,
{
struct ocf_mngt_cache_flush_context *context = priv;
ocf_cache_t cache = context->cache;
int result;
/* FIXME: need mechanism for async waiting for outstanding flushes to
* finish */
env_mutex_lock(&cache->flush_mutex);
result = env_mutex_trylock(&cache->flush_mutex);
if (result)
OCF_PL_FINISH_RET(pipeline, -OCF_ERR_FLUSH_IN_PROGRESS);
context->flags.lock = true;
ocf_refcnt_freeze(&cache->refcnt.dirty);
context->flags.freeze = true;
ocf_refcnt_register_zero_cb(&cache->refcnt.dirty,
_ocf_mngt_begin_flush_complete, context);
}
static void _ocf_mngt_end_flush(ocf_cache_t cache)
{
ocf_refcnt_unfreeze(&cache->refcnt.dirty);
env_mutex_unlock(&cache->flush_mutex);
}
bool ocf_mngt_core_is_dirty(ocf_core_t core)
{
return !!env_atomic_read(&core->runtime_meta->dirty_clines);
@ -606,7 +609,11 @@ static void _ocf_mngt_flush_finish(ocf_pipeline_t pipeline, void *priv,
ocf_cache_t cache = context->cache;
ocf_core_t core = context->core;
_ocf_mngt_end_flush(cache);
if (context->flags.freeze)
ocf_refcnt_unfreeze(&cache->refcnt.dirty);
if (context->flags.lock)
env_mutex_unlock(&cache->flush_mutex);
switch (context->op) {
case flush_cache:

View File

@ -41,6 +41,7 @@ class OcfErrorCode(IntEnum):
OCF_ERR_DIRTY_SHUTDOWN = auto()
OCF_ERR_DIRTY_EXISTS = auto()
OCF_ERR_FLUSHING_INTERRUPTED = auto()
OCF_ERR_FLUSH_IN_PROGRESS = auto()
OCF_ERR_CANNOT_ADD_CORE_TO_POOL = auto()
OCF_ERR_CACHE_IN_INCOMPLETE_STATE = auto()
OCF_ERR_CORE_IN_INACTIVE_STATE = auto()