Hold reference to module for each thread

To prevent removing cas_cache module when not all thread were stopped yet, each
of them should keep reference.

Signed-off-by: Michal Mielewczyk <michal.mielewczyk@intel.com>
This commit is contained in:
Michal Mielewczyk 2020-03-16 06:20:37 -04:00
parent 55d53867cc
commit f93019165f
2 changed files with 31 additions and 13 deletions

View File

@ -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;

View File

@ -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);