ASoC: wcd_cpe_services: Make the worker thread standalone
The worker thread can either be stopped through kthread_stop or could return from the function on some conditions. Since thread has two exit points, this is causing a race condition where kthread_stop indefinitely waits for the thread to exit. Make the thread standalone and always call do_exit itself to exit instead of stopping it through kthread_stop. CRs-fixed: 972943 Change-Id: If95cbd6ee895d566887453e98421d1514147441b Signed-off-by: Bhalchandra Gajare <gajare@codeaurora.org>
This commit is contained in:
parent
90c2030c5b
commit
72f0f4b937
1 changed files with 15 additions and 8 deletions
|
@ -161,6 +161,7 @@ struct cpe_command_node {
|
|||
struct cpe_info {
|
||||
struct list_head main_queue;
|
||||
struct completion cmd_complete;
|
||||
struct completion thread_comp;
|
||||
void *thread_handler;
|
||||
bool stop_thread;
|
||||
struct mutex msg_lock;
|
||||
|
@ -392,31 +393,34 @@ static int cpe_worker_thread(void *context)
|
|||
{
|
||||
struct cpe_info *t_info = (struct cpe_info *)context;
|
||||
|
||||
while (!kthread_should_stop()) {
|
||||
/*
|
||||
* Thread will run until requested to stop explicitly
|
||||
* by setting the t_info->stop_thread flag
|
||||
*/
|
||||
while (1) {
|
||||
/* Wait for command to be processed */
|
||||
wait_for_completion(&t_info->cmd_complete);
|
||||
|
||||
CPE_SVC_GRAB_LOCK(&t_info->msg_lock, "msg_lock");
|
||||
cpe_cmd_received(t_info);
|
||||
reinit_completion(&t_info->cmd_complete);
|
||||
/* Check if thread needs to be stopped */
|
||||
if (t_info->stop_thread)
|
||||
goto unlock_and_exit;
|
||||
CPE_SVC_REL_LOCK(&t_info->msg_lock, "msg_lock");
|
||||
};
|
||||
|
||||
pr_debug("%s: thread exited\n", __func__);
|
||||
return 0;
|
||||
|
||||
unlock_and_exit:
|
||||
pr_debug("%s: thread stopped\n", __func__);
|
||||
CPE_SVC_REL_LOCK(&t_info->msg_lock, "msg_lock");
|
||||
|
||||
return 0;
|
||||
complete_and_exit(&t_info->thread_comp, 0);
|
||||
}
|
||||
|
||||
static void cpe_create_worker_thread(struct cpe_info *t_info)
|
||||
{
|
||||
INIT_LIST_HEAD(&t_info->main_queue);
|
||||
init_completion(&t_info->cmd_complete);
|
||||
init_completion(&t_info->thread_comp);
|
||||
t_info->stop_thread = false;
|
||||
t_info->thread_handler = kthread_run(cpe_worker_thread,
|
||||
(void *)t_info, "cpe-worker-thread");
|
||||
|
@ -440,9 +444,12 @@ static void cpe_cleanup_worker_thread(struct cpe_info *t_info)
|
|||
complete(&t_info->cmd_complete);
|
||||
CPE_SVC_REL_LOCK(&t_info->msg_lock, "msg_lock");
|
||||
|
||||
kthread_stop(t_info->thread_handler);
|
||||
|
||||
/* Wait for the thread to exit */
|
||||
wait_for_completion(&t_info->thread_comp);
|
||||
t_info->thread_handler = NULL;
|
||||
|
||||
pr_debug("%s: Thread cleaned up successfully\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
static enum cpe_svc_result
|
||||
|
|
Loading…
Add table
Reference in a new issue