[alsa-devel] [PATCH 08/12] ASoC: SOF: ipc: fix a race, leading to IPC timeouts
Pierre-Louis Bossart
pierre-louis.bossart at linux.intel.com
Mon May 20 15:36:09 CEST 2019
>>> diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c
>>> index 065cb868bdfa..9dfdc02192b7 100644
>>> --- a/sound/soc/sof/intel/bdw.c
>>> +++ b/sound/soc/sof/intel/bdw.c
>>> @@ -278,11 +278,15 @@ static irqreturn_t bdw_irq_thread(int irq, void *context)
>>> /* reply message from DSP */
>>> if (ipcx & SHIM_IPCX_DONE &&
>>> !(imrx & SHIM_IMRX_DONE)) {
>>> + unsigned long flags;
>>> +
>>> /* Mask Done interrupt before return */
>>> snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR,
>>> SHIM_IMRX, SHIM_IMRX_DONE,
>>> SHIM_IMRX_DONE);
>>> + spin_lock_irqsave(&sdev->ipc_lock, flags);
>>
>> Here is an threaded irq handler, so the irqflag is superfluous.
>> You can use spin_lock_irq() and spin_unlock_irq().
>
> Oh, sure, thanks for catching this! That was a blind moving of the
> spin-lock from lower-level functions. I'll send an updated version to
> Pierre, unless you want to apply it immediately, in which case I can
> send it to you now.
I can send a v2 with Guennadi's update and Takashi's Reviewed-by tag.
>
>>> diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c
>>> index 7bf9143d3106..5a11a104110b 100644
>>> --- a/sound/soc/sof/intel/byt.c
>>> +++ b/sound/soc/sof/intel/byt.c
>>> @@ -324,11 +324,16 @@ static irqreturn_t byt_irq_thread(int irq, void *context)
>>> /* reply message from DSP */
>>> if (ipcx & SHIM_BYT_IPCX_DONE &&
>>> !(imrx & SHIM_IMRX_DONE)) {
>>> + unsigned long flags;
>>> +
>>> /* Mask Done interrupt before first */
>>> snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR,
>>> SHIM_IMRX,
>>> SHIM_IMRX_DONE,
>>> SHIM_IMRX_DONE);
>>
>> BTW, is this usage of _unlocked() version safe? The previous one also
>> contained that, and I wonder why _unlocked variant must be used here.
>
> Some of those uses seem rather fragile to me too, but it looks like they
> *should* be safe in normal cases. There seem to be a potential problem
> on Broadwell, where an ISR is first configured, which uses *_unlocked()
> to access the SHIM_IMRX register, and then bdw_set_dsp_D0() is called,
> which also touches that register. So, it's relying on the fact, that no
> IPC interrupts will occur until probing is completed. This should also
> normally be the case, but if for some reason such an interrupt does
> trigger at that time, access to that register can be messed up. This
> should be reviewed and possibly refined separately.
There will be additional IPC hardening fixes that are being tested at
the moment, the introduction of HDaudio support seems to have exposed a
number of issues we didn't see with I2S/TDM/DMIC interfaces. I included
Guennadi's patch in the series since we have evidence it does improve
things on the Up2. we can look at the _unlocked parts in the next update
with more validation.
More information about the Alsa-devel
mailing list