diff --git a/modules/cas_cache/layer_cache_management.c b/modules/cas_cache/layer_cache_management.c index 9b6824c..444e662 100644 --- a/modules/cas_cache/layer_cache_management.c +++ b/modules/cas_cache/layer_cache_management.c @@ -366,7 +366,7 @@ struct _cache_mngt_stop_context { struct _cache_mngt_async_context async; int error; ocf_cache_t cache; - struct work_struct work; + struct task_struct *finish_thread; }; static int exit_instance_finish(void *data) @@ -410,6 +410,7 @@ struct _cache_mngt_attach_context { ocf_cache_t cache; int ocf_start_error; struct work_struct work; + struct task_struct *rollback_thread; struct { bool priv_inited:1; @@ -426,6 +427,9 @@ static int cache_start_rollback(void *data) ocf_cache_t cache = ctx->cache; int result; + if (kthread_should_stop()) + return 0; + if (ctx->cls_inited) cas_cls_deinit(cache); @@ -455,28 +459,22 @@ static void _cache_mngt_cache_stop_rollback_complete(ocf_cache_t cache, void *priv, int error) { struct _cache_mngt_attach_context *ctx = priv; - struct task_struct *thread; if (error == -OCF_ERR_WRITE_CACHE) printk(KERN_WARNING "Cannot save cache state\n"); else BUG_ON(error); - thread = kthread_run(cache_start_rollback, ctx, - "cas_cache_rollback_complete"); - BUG_ON(IS_ERR(thread)); + BUG_ON(!wake_up_process(ctx->rollback_thread)); } static void _cache_mngt_cache_stop_complete(ocf_cache_t cache, void *priv, int error) { struct _cache_mngt_stop_context *context = priv; - struct task_struct *thread; context->error = error; - thread = kthread_run(exit_instance_finish, context, - "cas_cache_stop_complete"); - BUG_ON(IS_ERR(thread)); + BUG_ON(!wake_up_process(context->finish_thread)); } static int _cache_mngt_cache_stop_sync(ocf_cache_t cache) @@ -488,6 +486,13 @@ static int _cache_mngt_cache_stop_sync(ocf_cache_t cache) if (!context) return -ENOMEM; + context->finish_thread = kthread_create(exit_instance_finish, context, + "cas_cache_stop_complete"); + if (!context->finish_thread) { + kfree(context); + return -ENOMEM; + } + _cache_mngt_async_context_init(&context->async); context->error = 0; context->cache = cache; @@ -1693,6 +1698,8 @@ static void cache_start_finalize(struct work_struct *work) return; } + kthread_stop(ctx->rollback_thread); + ocf_mngt_cache_unlock(cache); } @@ -1728,7 +1735,7 @@ static int _cache_mngt_cache_priv_init(ocf_cache_t cache) cache_priv = vzalloc(sizeof(*cache_priv) + cpus_no * sizeof(*cache_priv->io_queues)); if (!cache_priv) - return -OCF_ERR_NO_MEM; + return -ENOMEM; atomic_set(&cache_priv->flush_interrupt_enabled, 1); @@ -1823,6 +1830,14 @@ int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg, return -ENOMEM; } + context->rollback_thread = kthread_create(cache_start_rollback, context, + "cas_cache_rollback_complete"); + if (!context->rollback_thread) { + kfree(context); + module_put(THIS_MODULE); + return -ENOMEM; + } + context->device_cfg = device_cfg; context->cmd = cmd; _cache_mngt_async_context_init(&context->async); @@ -1832,6 +1847,7 @@ int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg, */ result = ocf_mngt_cache_start(cas_ctx, &cache, cfg); if (result) { + kthread_stop(context->rollback_thread); kfree(context); module_put(THIS_MODULE); return result; diff --git a/modules/cas_cache/threads.c b/modules/cas_cache/threads.c index 2513fd5..0345d63 100644 --- a/modules/cas_cache/threads.c +++ b/modules/cas_cache/threads.c @@ -54,7 +54,7 @@ static int _cas_io_queue_thread(void *data) wait_for_completion(&info->compl); printk(KERN_DEBUG "Thread %s stopped\n", info->name); kfree(info); - do_exit(0); + module_put_and_exit(0); return 0; } @@ -115,7 +115,7 @@ static int _cas_cleaner_thread(void *data) wait_for_completion(&info->compl); kfree(info); - do_exit(0); + module_put_and_exit(0); return 0; } @@ -149,7 +149,7 @@ static int _cas_metadata_updater_thread(void *data) wait_for_completion(&info->compl); kfree(info); - do_exit(0); + module_put_and_exit(0); return 0; } @@ -183,6 +183,8 @@ static int _cas_create_thread(struct cas_thread_info **pinfo, } info->thread = thread; + BUG_ON(!try_module_get(THIS_MODULE)); + /* Affinitize thread to core */ if (cpu != CAS_CPUS_ALL) kthread_bind(thread, cpu);