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:
Bhalchandra Gajare 2016-02-04 15:14:57 -08:00 committed by David Keitel
parent 90c2030c5b
commit 72f0f4b937

View file

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