From a057a0082fe1c485858ceabd5ef439d4fc8d08d2 Mon Sep 17 00:00:00 2001 From: Slawomir Jankowski Date: Mon, 18 Jan 2021 12:47:09 +0100 Subject: [PATCH] Handle cache stopping interruption Ignore the interruption of the stop operation - will finish asynchronously. Remove redundant `ocf_queue_put`. Move creating the `finish_thread` during the cache stop from the `_cache_mngt_cache_stop_sync` to the `cache_mngt_exit_instance` and give it a proper handling. Signed-off-by: Slawomir Jankowski --- modules/cas_cache/layer_cache_management.c | 36 ++++++++++++---------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/modules/cas_cache/layer_cache_management.c b/modules/cas_cache/layer_cache_management.c index e7bccac..49d76a8 100644 --- a/modules/cas_cache/layer_cache_management.c +++ b/modules/cas_cache/layer_cache_management.c @@ -585,7 +585,6 @@ static void _cache_mngt_cache_stop_complete(ocf_cache_t cache, void *priv, { struct _cache_mngt_stop_context *context = priv; context->error = error; - BUG_ON(!wake_up_process(context->finish_thread)); } @@ -598,12 +597,6 @@ static int _cache_mngt_cache_stop_sync(ocf_cache_t cache) cache_priv = ocf_cache_get_priv(cache); context = cache_priv->stop_context; - context->finish_thread = kthread_create( - exit_instance_finish, cache_priv->stop_context, "cas_%s_stop", - ocf_cache_get_name(cache)); - if (!context->finish_thread) - return -ENOMEM; - _cache_mngt_async_context_init(&context->async); context->error = 0; context->cache = cache; @@ -1990,10 +1983,10 @@ int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg, context->rollback_thread = kthread_create(cache_start_rollback, context, "cas_cache_rollback_complete"); - if (!context->rollback_thread) { + if (IS_ERR(context->rollback_thread)) { kfree(context); module_put(THIS_MODULE); - return -ENOMEM; + return PTR_ERR(context->rollback_thread); } context->device_cfg = device_cfg; @@ -2283,6 +2276,7 @@ int cache_mngt_exit_instance(const char *cache_name, size_t name_len, int flush) struct cache_priv *cache_priv; ocf_queue_t mngt_queue; int status = 0, flush_status = 0; + struct _cache_mngt_stop_context *context; status = ocf_mngt_cache_get_by_name(cas_ctx, cache_name, name_len, &cache); @@ -2291,6 +2285,14 @@ int cache_mngt_exit_instance(const char *cache_name, size_t name_len, int flush) cache_priv = ocf_cache_get_priv(cache); mngt_queue = cache_priv->mngt_queue; + context = cache_priv->stop_context; + + context->finish_thread = kthread_create(exit_instance_finish, + context, "cas_%s_stop", cache_name); + if (IS_ERR(context->finish_thread)) { + status = PTR_ERR(context->finish_thread); + goto put; + } /* * Flush cache. Flushing may take a long time, so we allow user @@ -2307,7 +2309,7 @@ int cache_mngt_exit_instance(const char *cache_name, size_t name_len, int flush) case -OCF_ERR_CACHE_IN_INCOMPLETE_STATE: case -OCF_ERR_FLUSHING_INTERRUPTED: case -KCAS_ERR_WAITING_INTERRUPTED: - goto put; + goto stop_thread; default: flush_status = status; break; @@ -2315,7 +2317,7 @@ int cache_mngt_exit_instance(const char *cache_name, size_t name_len, int flush) status = _cache_mngt_lock_sync(cache); if (status) - goto put; + goto stop_thread; if (!cas_upgrade_is_in_upgrade()) { /* If we are not in upgrade - destroy cache devices */ @@ -2344,17 +2346,19 @@ int cache_mngt_exit_instance(const char *cache_name, size_t name_len, int flush) if (flush && !flush_status) BUG_ON(ocf_mngt_cache_is_dirty(cache)); - /* Stop cache device */ + /* Stop cache device - ignore interrupts */ status = _cache_mngt_cache_stop_sync(cache); - if (status == -ENOMEM) - goto unlock; - - ocf_queue_put(mngt_queue); + if (status == -KCAS_ERR_WAITING_INTERRUPTED) + printk(KERN_WARNING + "Waiting for cache stop interrupted. " + "Stop will finish asynchronously.\n"); return status; unlock: ocf_mngt_cache_unlock(cache); +stop_thread: + kthread_stop(context->finish_thread); put: ocf_mngt_cache_put(cache); return status;