From 0f6dc526558d3c714918e9d9845ed9ebae4904db Mon Sep 17 00:00:00 2001 From: Swati Sachdeva Date: Fri, 25 Oct 2019 16:28:13 +0530 Subject: [PATCH] nvadsp: Fixing adsp_ff_exit function - ADSP thread was waiting on a sempaphore to wake up - In case of shutdown when kthread_stop is called, kthread_should_stop - will not be called if thread is not woken up - Solution: Replace semaphore with wait_queue and use - wait_event_interruptible - wake up the thread if either there is a message in the list or - kthread_should_stop is true Bug 2739934 Bug 200560194 Bug 200463529 Change-Id: Iea04e0100248f554076aaed8627d40f5b96df2bf Signed-off-by: Uday Gupta Reviewed-on: https://git-master.nvidia.com/r/2232868 (cherry picked from commit a3a81a984a933a8f580154b76098119427f5e19e) Signed-off-by: Dipesh Gandhi Reviewed-on: https://git-master.nvidia.com/r/2238825 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Swati Sachdeva Reviewed-by: Nitin Pai Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/platform/tegra/nvadsp/adspff.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/platform/tegra/nvadsp/adspff.c b/drivers/platform/tegra/nvadsp/adspff.c index 2c0c82e9..0655c4a3 100644 --- a/drivers/platform/tegra/nvadsp/adspff.c +++ b/drivers/platform/tegra/nvadsp/adspff.c @@ -517,8 +517,8 @@ static const struct sched_param param = { .sched_priority = 1, }; static struct task_struct *adspff_kthread; -static DECLARE_COMPLETION(adspff_kthread_completion); static struct list_head adspff_kthread_msgq_head; +static wait_queue_head_t wait_queue; struct adspff_kthread_msg { uint32_t msg_id; @@ -533,13 +533,12 @@ static int adspff_kthread_fn(void *data) unsigned long flags; while (1) { - if (kthread_should_stop()) - do_exit(ret); - /* Wait for 10 secs or until woken up (earlier) */ - if (!wait_for_completion_timeout(&adspff_kthread_completion, - msecs_to_jiffies(10 * 1000))) - continue; /* Timeout */ + ret = wait_event_interruptible(wait_queue, kthread_should_stop() + || !list_empty(&adspff_kthread_msgq_head)); + + if (kthread_should_stop()) + do_exit(0); if (!list_empty(&adspff_kthread_msgq_head)) { kmsg = list_first_entry(&adspff_kthread_msgq_head, @@ -593,7 +592,7 @@ static int adspff_msg_handler(uint32_t msg, void *data) kmsg->msg_id = msg; list_add_tail(&kmsg->list, &adspff_kthread_msgq_head); - complete(&adspff_kthread_completion); + wake_up(&wait_queue); spin_unlock_irqrestore(&adspff_lock, flags); return 0; @@ -676,6 +675,8 @@ int adspff_init(struct platform_device *pdev) INIT_LIST_HEAD(&adspff_kthread_msgq_head); INIT_LIST_HEAD(&file_list); + // kthread inIt + init_waitqueue_head(&wait_queue); adspff_kthread = kthread_create(adspff_kthread_fn, NULL, "adspp_kthread"); sched_setscheduler(adspff_kthread, SCHED_FIFO, ¶m);