Handle cache start finalize synchronously

Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
This commit is contained in:
Robert Baldyga 2020-12-31 16:36:02 +01:00
parent e623c44b3b
commit 238b11846b
2 changed files with 56 additions and 77 deletions

View File

@ -58,7 +58,6 @@ struct cas_classifier;
struct cache_priv { struct cache_priv {
uint64_t core_id_bitmap[DIV_ROUND_UP(OCF_CORE_MAX, 8*sizeof(uint64_t))]; uint64_t core_id_bitmap[DIV_ROUND_UP(OCF_CORE_MAX, 8*sizeof(uint64_t))];
struct cas_classifier *classifier; struct cas_classifier *classifier;
struct work_struct start_worker;
struct _cache_mngt_stop_context *stop_context; struct _cache_mngt_stop_context *stop_context;
atomic_t flush_interrupt_enabled; atomic_t flush_interrupt_enabled;
ocf_queue_t mngt_queue; ocf_queue_t mngt_queue;

View File

@ -52,18 +52,6 @@ static int _cache_mngt_async_callee_set_result(
return ret == ASYNC_CALL_FINISHED ? 0 : ret; return ret == ASYNC_CALL_FINISHED ? 0 : ret;
} }
static int _cache_mngt_async_callee_peek_result(
struct _cache_mngt_async_context *context)
{
int result;
spin_lock(&context->lock);
result = context->result;
spin_unlock(&context->lock);
return result;
}
static int _cache_mngt_async_caller_set_result( static int _cache_mngt_async_caller_set_result(
struct _cache_mngt_async_context *context, struct _cache_mngt_async_context *context,
int error) int error)
@ -1834,72 +1822,26 @@ static void init_instance_complete(struct _cache_mngt_attach_context *ctx,
name, MAX_ELEVATOR_NAME); name, MAX_ELEVATOR_NAME);
} }
static void _cache_mngt_start_complete(ocf_cache_t cache, void *priv,
int error);
static void cache_start_finalize(struct work_struct *work)
{
struct cache_priv *cache_priv =
container_of(work, struct cache_priv, start_worker);
struct task_struct *rollback_thread;
struct _cache_mngt_attach_context *ctx = cache_priv->attach_context;
int result;
ocf_cache_t cache = ctx->cache;
result = cas_cls_init(cache);
if (result) {
ctx->ocf_start_error = result;
return _cache_mngt_start_complete(cache, ctx, result);
}
ctx->cls_inited = true;
result = cache_mngt_initialize_core_objects(cache);
if (result) {
ctx->ocf_start_error = result;
return _cache_mngt_start_complete(cache, ctx, result);
}
ocf_core_visit(cache, _cache_mngt_core_device_loaded_visitor,
NULL, false);
init_instance_complete(ctx, cache);
rollback_thread = ctx->rollback_thread;
if (_cache_mngt_async_callee_set_result(&ctx->async, 0)) {
/* caller interrupted */
ctx->ocf_start_error = 0;
ocf_mngt_cache_stop(cache,
_cache_mngt_cache_stop_rollback_complete, ctx);
return;
}
kthread_stop(rollback_thread);
ocf_mngt_cache_unlock(cache);
}
static void _cache_mngt_start_complete(ocf_cache_t cache, void *priv, int error) static void _cache_mngt_start_complete(ocf_cache_t cache, void *priv, int error)
{ {
struct _cache_mngt_attach_context *ctx = priv; struct _cache_mngt_attach_context *ctx = priv;
struct cache_priv *cache_priv = ocf_cache_get_priv(cache); int caller_status;
int caller_status = _cache_mngt_async_callee_peek_result(&ctx->async);
if (caller_status || error) {
if (error == -OCF_ERR_NO_FREE_RAM && ctx->cmd) { if (error == -OCF_ERR_NO_FREE_RAM && ctx->cmd) {
ocf_mngt_get_ram_needed(cache, ctx->device_cfg, ocf_mngt_get_ram_needed(cache, ctx->device_cfg,
&ctx->cmd->min_free_ram); &ctx->cmd->min_free_ram);
} else if (caller_status == -KCAS_ERR_WAITING_INTERRUPTED) { }
caller_status =_cache_mngt_async_callee_set_result(&ctx->async, error);
if (caller_status == -KCAS_ERR_WAITING_INTERRUPTED) {
/* Attach/load was interrupted. Rollback asynchronously. */
if (!error) {
printk(KERN_WARNING "Cache added successfully, " printk(KERN_WARNING "Cache added successfully, "
"but waiting interrupted. Rollback\n"); "but waiting interrupted. Rollback\n");
} }
ctx->ocf_start_error = error; ctx->ocf_start_error = error;
ocf_mngt_cache_stop(cache, _cache_mngt_cache_stop_rollback_complete, ocf_mngt_cache_stop(cache,
ctx); _cache_mngt_cache_stop_rollback_complete, ctx);
} else {
_cache_mngt_log_cache_device_path(cache, ctx->device_cfg);
schedule_work(&cache_priv->start_worker);
} }
} }
@ -1921,7 +1863,6 @@ static int _cache_mngt_cache_priv_init(ocf_cache_t cache)
} }
atomic_set(&cache_priv->flush_interrupt_enabled, 1); atomic_set(&cache_priv->flush_interrupt_enabled, 1);
INIT_WORK(&cache_priv->start_worker , cache_start_finalize);
ocf_cache_set_priv(cache, cache_priv); ocf_cache_set_priv(cache, cache_priv);
@ -1988,6 +1929,35 @@ out_bdev:
return result; return result;
} }
static int _cache_start_finalize(ocf_cache_t cache)
{
struct cache_priv *cache_priv = ocf_cache_get_priv(cache);
struct _cache_mngt_attach_context *ctx = cache_priv->attach_context;
int result;
_cache_mngt_log_cache_device_path(cache, ctx->device_cfg);
result = cas_cls_init(cache);
if (result) {
ctx->ocf_start_error = result;
return result;
}
ctx->cls_inited = true;
result = cache_mngt_initialize_core_objects(cache);
if (result) {
ctx->ocf_start_error = result;
return result;
}
ocf_core_visit(cache, _cache_mngt_core_device_loaded_visitor,
NULL, false);
init_instance_complete(ctx, cache);
return 0;
}
int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg, int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg,
struct ocf_mngt_cache_device_config *device_cfg, struct ocf_mngt_cache_device_config *device_cfg,
struct kcas_start_cache *cmd) struct kcas_start_cache *cmd)
@ -2060,15 +2030,26 @@ int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg,
result = wait_for_completion_interruptible(&context->async.cmpl); result = wait_for_completion_interruptible(&context->async.cmpl);
result = _cache_mngt_async_caller_set_result(&context->async, result); result = _cache_mngt_async_caller_set_result(&context->async, result);
if (result == -KCAS_ERR_WAITING_INTERRUPTED)
return result;
if (result)
goto err;
result = _cache_start_finalize(cache);
if (result)
goto err;
kthread_stop(context->rollback_thread);
if (result != -KCAS_ERR_WAITING_INTERRUPTED)
kfree(context); kfree(context);
if (!result)
cache_priv->attach_context = NULL; cache_priv->attach_context = NULL;
ocf_mngt_cache_unlock(cache);
return result; return result;
err: err:
_cache_mngt_async_context_init(&context->async);
ocf_mngt_cache_stop(cache, _cache_mngt_cache_stop_rollback_complete, ocf_mngt_cache_stop(cache, _cache_mngt_cache_stop_rollback_complete,
context); context);
rollback_result = wait_for_completion_interruptible(&context->async.cmpl); rollback_result = wait_for_completion_interruptible(&context->async.cmpl);
@ -2306,7 +2287,6 @@ int cache_mngt_exit_instance(const char *cache_name, size_t name_len, int flush)
cache_priv = ocf_cache_get_priv(cache); cache_priv = ocf_cache_get_priv(cache);
mngt_queue = cache_priv->mngt_queue; mngt_queue = cache_priv->mngt_queue;
cancel_work_sync(&cache_priv->start_worker);
/* /*
* Flush cache. Flushing may take a long time, so we allow user * Flush cache. Flushing may take a long time, so we allow user