diff options
author | Daniel Baluta <daniel.baluta@nxp.com> | 2019-03-27 10:25:22 +0200 |
---|---|---|
committer | Dong Aisheng <aisheng.dong@nxp.com> | 2019-11-25 15:52:20 +0800 |
commit | 6bfa0c442b69c07b45e74f00704f74fd1ad99fa5 (patch) | |
tree | 133d59f427e68c686aacbe733c2bdb454f8f662d /sound/soc/fsl/fsl_dsp.c | |
parent | 940d9baeca0f6d7782f8dc59e0b6f0db85fa2325 (diff) |
MLK-21144 ASoC: fsl: Fix crash with multiple open/close
Because we are re-initializing the proxy at close it might
happen that work is still pending which causes the following crash:
[ 94.699835] Unable to handle kernel NULL pointer dereference at virtual address 00000008
[ 94.707923] Mem abort info:
[ 94.710722] Exception class = DABT (current EL), IL = 32 bits
[ 94.716637] SET = 0, FnV = 0
[ 94.719686] EA = 0, S1PTW = 0
[ 94.722822] Data abort info:
[ 94.725698] ISV = 0, ISS = 0x00000005
[ 94.729530] CM = 0, WnR = 0
[ 94.732504] user pgtable: 4k pages, 48-bit VAs, pgd = ffff8008d9ba3000
[ 94.739035] [0000000000000008] *pgd=0000000938419003, *pud=0000000000000000
[ 94.746015] Internal error: Oops: 96000005 [#1] PREEMPT SMP
[ 94.751589] Modules linked in:
[ 94.754652] CPU: 0 PID: 2068 Comm: kworker/0:2 Not tainted 4.14.98-dirty #75
[ 94.761700] Hardware name: Freescale i.MX8QM MEK (DT)
[ 94.766768] task: ffff8008f23ae200 task.stack: ffff000014378000
[ 94.772705] PC is at process_one_work+0x34/0x414
[ 94.777325] LR is at process_one_work+0x1e0/0x414
In order to fix this, we make sure that no work is pending before starting
the re-initialization.
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
Reviewed-by: Shengjiu Wang <shengjiu.wang@nxp.com>
(cherry picked from commit 2c00c24be5f8b63636e3f9005e15a3de42058438)
Diffstat (limited to 'sound/soc/fsl/fsl_dsp.c')
-rw-r--r-- | sound/soc/fsl/fsl_dsp.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/sound/soc/fsl/fsl_dsp.c b/sound/soc/fsl/fsl_dsp.c index 2c7976ffdb09..b3bcf21730d2 100644 --- a/sound/soc/fsl/fsl_dsp.c +++ b/sound/soc/fsl/fsl_dsp.c @@ -430,8 +430,12 @@ int fsl_dsp_close_func(struct xf_client *client) /* If device is free, reinitialize the resource of * dsp driver and framework */ - if (atomic_long_read(&dsp_priv->refcnt) <= 0) + if (atomic_long_read(&dsp_priv->refcnt) <= 0) { + /* we are closing up, wait for proxy processing + * function to finish */ + cancel_work_sync(&dsp_priv->proxy.work); resource_release(dsp_priv); + } mutex_unlock(&dsp_priv->dsp_mutex); |