diff --git a/modules/cas_cache/cas_cache.h b/modules/cas_cache/cas_cache.h index 53843dc..e5139b6 100644 --- a/modules/cas_cache/cas_cache.h +++ b/modules/cas_cache/cas_cache.h @@ -58,6 +58,7 @@ struct cas_classifier; struct cache_priv { uint64_t core_id_bitmap[DIV_ROUND_UP(OCF_CORE_MAX, 8*sizeof(uint64_t))]; struct cas_classifier *classifier; + struct _cache_mngt_stop_context *stop_context; atomic_t flush_interrupt_enabled; ocf_queue_t mngt_queue; ocf_queue_t io_queues[]; diff --git a/modules/cas_cache/layer_cache_management.c b/modules/cas_cache/layer_cache_management.c index 444e662..42f9887 100644 --- a/modules/cas_cache/layer_cache_management.c +++ b/modules/cas_cache/layer_cache_management.c @@ -355,13 +355,6 @@ static int _cache_mngt_core_flush_uninterruptible(ocf_core_t core) return result; } -static void _cache_mngt_cache_priv_deinit(ocf_cache_t cache) -{ - struct cache_priv *cache_priv = ocf_cache_get_priv(cache); - - vfree(cache_priv); -} - struct _cache_mngt_stop_context { struct _cache_mngt_async_context async; int error; @@ -369,6 +362,16 @@ struct _cache_mngt_stop_context { struct task_struct *finish_thread; }; +static void _cache_mngt_cache_priv_deinit(ocf_cache_t cache) +{ + struct cache_priv *cache_priv = ocf_cache_get_priv(cache); + + kthread_stop(cache_priv->stop_context->finish_thread); + kfree(cache_priv->stop_context); + + vfree(cache_priv); +} + static int exit_instance_finish(void *data) { struct cache_priv *cache_priv; @@ -377,6 +380,9 @@ static int exit_instance_finish(void *data) bool flush_status; int result = 0; + if (kthread_should_stop()) + return 0; + flush_status = ocf_mngt_cache_is_dirty(ctx->cache); cache_priv = ocf_cache_get_priv(ctx->cache); mngt_queue = cache_priv->mngt_queue; @@ -479,19 +485,12 @@ static void _cache_mngt_cache_stop_complete(ocf_cache_t cache, void *priv, static int _cache_mngt_cache_stop_sync(ocf_cache_t cache) { + struct cache_priv *cache_priv; struct _cache_mngt_stop_context *context; int result = 0; - context = env_malloc(sizeof(*context), GFP_KERNEL); - 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_priv = ocf_cache_get_priv(cache); + context = cache_priv->stop_context; _cache_mngt_async_context_init(&context->async); context->error = 0; @@ -1737,6 +1736,21 @@ static int _cache_mngt_cache_priv_init(ocf_cache_t cache) if (!cache_priv) return -ENOMEM; + cache_priv->stop_context = + env_malloc(sizeof(*cache_priv->stop_context), GFP_KERNEL); + if (!cache_priv->stop_context) { + kfree(cache_priv); + return -ENOMEM; + } + + cache_priv->stop_context->finish_thread = kthread_create( + exit_instance_finish, cache_priv->stop_context, "cas_cache_stop_complete"); + if (!cache_priv->stop_context->finish_thread) { + kfree(cache_priv->stop_context); + kfree(cache_priv); + return -ENOMEM; + } + atomic_set(&cache_priv->flush_interrupt_enabled, 1); ocf_cache_set_priv(cache, cache_priv);