From a821464fca1ba12bb4b0cd835fd87f0d8d2c3b62 Mon Sep 17 00:00:00 2001 From: Bartosz Kokoszko Date: Fri, 8 Nov 2019 10:48:30 +0100 Subject: [PATCH 1/3] dmic: add missing schedule_task_cancel() in dmic_stop() After trigger stop we should cancel dmic task from low latency scheduler. Signed-off-by: Bartosz Kokoszko (cherry picked from commit 6071fb8dbf07f35db398b645ca4ceaf98779f071) --- src/drivers/intel/cavs/dmic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/drivers/intel/cavs/dmic.c b/src/drivers/intel/cavs/dmic.c index 6c4240c0191c..49a2b6f9fd86 100644 --- a/src/drivers/intel/cavs/dmic.c +++ b/src/drivers/intel/cavs/dmic.c @@ -1417,6 +1417,7 @@ static void dmic_stop(struct dai *dai) dmic_active_fifos--; + schedule_task_cancel(&dmic->dmicwork); out: spin_unlock(dai->lock); } From fe5665fbf8944a2518a73c9511c0344f3369a783 Mon Sep 17 00:00:00 2001 From: Bartosz Kokoszko Date: Fri, 8 Nov 2019 10:55:33 +0100 Subject: [PATCH 2/3] spinlock: add return value to spin_try_lock macro Adds return to spin_try_lock() in order to retrieve status from arch_try_lock() function. Signed-off-by: Bartosz Kokoszko (cherry picked from commit b03e15a7657943095db3189f150020dc3d41bc69) --- src/include/sof/spinlock.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/include/sof/spinlock.h b/src/include/sof/spinlock.h index e0f95152dc85..44eeebd2984e 100644 --- a/src/include/sof/spinlock.h +++ b/src/include/sof/spinlock.h @@ -189,10 +189,10 @@ extern uint32_t lock_dbg_user[DBG_LOCK_USERS]; arch_spin_lock(lock); \ } while (0) -#define spin_try_lock(lock) \ +#define spin_try_lock(lock, ret) \ do { \ spin_lock_dbg(); \ - arch_try_lock(lock); \ + ret = arch_try_lock(lock); \ } while (0) #define spin_unlock(lock) \ From dcf99d051b41b41ac4185151f167113d2d132326 Mon Sep 17 00:00:00 2001 From: Bartosz Kokoszko Date: Fri, 8 Nov 2019 11:09:51 +0100 Subject: [PATCH 3/3] dmic: change spin_lock to spin_try_lock in dmic_work() In order to avoid dead locks in dmic_work I've replaced spin_lock() with spin_try_lock(). In case when spin_try_lock() fails we reschedule dmic work. Signed-off-by: Bartosz Kokoszko (cherry picked from commit 6a0cf6740f705e216a3d132c8b05b84d2f8d0bad) --- src/drivers/intel/cavs/dmic.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/drivers/intel/cavs/dmic.c b/src/drivers/intel/cavs/dmic.c index 49a2b6f9fd86..a7880561d3cf 100644 --- a/src/drivers/intel/cavs/dmic.c +++ b/src/drivers/intel/cavs/dmic.c @@ -175,9 +175,16 @@ static enum task_state dmic_work(void *data) int32_t gval; uint32_t val; int i; + int ret; tracev_dmic("dmic_work()"); - spin_lock(dai->lock); + + spin_try_lock(dai->lock, ret); + if (!ret) { + tracev_dmic("dmic_work(): spin_try_lock(dai->lock, ret)" + "failed: RESCHEDULE"); + return SOF_TASK_STATE_RESCHEDULE; + } /* Increment gain with logarithmic step. * Gain is Q2.30 and gain modifier is Q12.20.