aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/intel/skylake
diff options
context:
space:
mode:
authorGustaw Lewandowski <gustaw.lewandowski@intel.com>2019-06-13 21:04:33 +0200
committerMark Brown <broonie@kernel.org>2019-06-25 15:33:43 +0100
commit26ae20490809db30677dfd54f81a73ce77ba2df1 (patch)
tree8548945ce79e174debdbccfb936a89889493a443 /sound/soc/intel/skylake
parentASoC: Intel: Skylake: Read HIPCT extension before clearing DONE bit (diff)
downloadlinux-dev-26ae20490809db30677dfd54f81a73ce77ba2df1.tar.xz
linux-dev-26ae20490809db30677dfd54f81a73ce77ba2df1.zip
ASoC: Intel: Fix race condition in IPC rx list
Since there are multiple IPCs being sent in a short span of time, there is a possibility of more than one message being on the Rx list after receiving response from firmware. In such cases, when the first notification of interrupt from firmware is received, driver retrieves the message from the Rx list but does not delete it from the list till the next lock. In the meantime, when another interrupt is received from the firmware, driver is reading the previous message again since the previous message has not been removed from the list. Signed-off-by: Gustaw Lewandowski <gustaw.lewandowski@intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/intel/skylake')
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c
index 5c9206dc7932..5094205a243f 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.c
+++ b/sound/soc/intel/skylake/skl-sst-ipc.c
@@ -344,6 +344,7 @@ static struct ipc_message *skl_ipc_reply_get_msg(struct sst_generic_ipc *ipc,
msg = list_first_entry(&ipc->rx_list, struct ipc_message, list);
+ list_del(&msg->list);
out:
return msg;
@@ -488,7 +489,6 @@ void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
}
spin_lock_irqsave(&ipc->dsp->spinlock, flags);
- list_del(&msg->list);
sst_ipc_tx_msg_reply_complete(ipc, msg);
spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
}