* Re: [question about DPCM] dpcm_be_disconnect race condition
[not found] <53FD9384.3020501@marvell.com>
@ 2014-08-27 18:52 ` Mark Brown
2014-08-28 2:07 ` Qiao Zhou
0 siblings, 1 reply; 3+ messages in thread
From: Mark Brown @ 2014-08-27 18:52 UTC (permalink / raw)
To: Qiao Zhou
Cc: tiwai@suse.de, Xin Qian, alsa-devel@alsa-project.org,
Liam Girdwood
[-- Attachment #1.1: Type: text/plain, Size: 2171 bytes --]
On Wed, Aug 27, 2014 at 04:15:00PM +0800, Qiao Zhou wrote:
> Hi Liam, Mark
>
> I'm developing audio with DPCM on one phone platform, and met one kernel
> panic issue related with dpcm_be_connect. Could you please help to suggest?
Adding Liam.
> Taking audio playback for example:
> 1. User space writes all the data into audio buffer. When the blocking write
> returns, it closes audio path(which updates dapm and triggers
> soc_dpcm_runtime_update).
> 2. When user space closes audio path, kernel audio driver(DMA) is still
> transferring data from audio buffer to audio peripheral. So DMA interrupt
> will come, and the interrupt handler runs on different cpu comparing to
> which the task to close audio path runs on.
> 3. Due to system schedule, below case may happen.
>
> cpu0 cpu1
>
> soc_dapm_mixer_update_power -> | DMA interrupt ->
> soc_dpcm_runtime_update -> | snd_pcm_period_elapsed ->
> dpcm_be_disconnect(old) -> | snd_pcm_update_hw_ptr0 ->
> __________________________ | xrun ->
> | | | snd_pcm_stop ->
> |list_del(&dpcm->list_be) | | dpcm_fe_dai_trigger ->
> |list_del(&dpcm->list_fe) | | dpcm_be_dai_trigger ->
> |kfree(dpcm); | | list_for_each_entry(dpcm..
> |_________________________| |
>
> On CPU1, list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
> will get dpcm and corresponding be, but there is no protection against the
> dpcm_be_disconnect on cpu0. Related dpcm for the BE may be invalid/freed
> when cpu1 tries to access it.
> Should we require user space to make sure audio transfer ends before closing
> audio path to avoid such issue? I'm not sure if I missed anything or used it
> wrongly.
Well, it should do that in general if it wants to make sure that the
audio actually gets played but the kernel should protect against this.
We should be holding a lock whenever we update the lists.
> Thanks in advance!
> --
>
> Best Regards
> Qiao
>
[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [question about DPCM] dpcm_be_disconnect race condition
2014-08-27 18:52 ` [question about DPCM] dpcm_be_disconnect race condition Mark Brown
@ 2014-08-28 2:07 ` Qiao Zhou
2014-08-28 8:58 ` Mark Brown
0 siblings, 1 reply; 3+ messages in thread
From: Qiao Zhou @ 2014-08-28 2:07 UTC (permalink / raw)
To: Mark Brown
Cc: tiwai@suse.de, Xin Qian, alsa-devel@alsa-project.org,
Liam Girdwood
On 08/28/2014 02:52 AM, Mark Brown wrote:
> On Wed, Aug 27, 2014 at 04:15:00PM +0800, Qiao Zhou wrote:
>> Hi Liam, Mark
>>
>> I'm developing audio with DPCM on one phone platform, and met one kernel
>> panic issue related with dpcm_be_connect. Could you please help to suggest?
>
> Adding Liam.
>
>> Taking audio playback for example:
>> 1. User space writes all the data into audio buffer. When the blocking write
>> returns, it closes audio path(which updates dapm and triggers
>> soc_dpcm_runtime_update).
>> 2. When user space closes audio path, kernel audio driver(DMA) is still
>> transferring data from audio buffer to audio peripheral. So DMA interrupt
>> will come, and the interrupt handler runs on different cpu comparing to
>> which the task to close audio path runs on.
>> 3. Due to system schedule, below case may happen.
>>
>> cpu0 cpu1
>>
>> soc_dapm_mixer_update_power -> | DMA interrupt ->
>> soc_dpcm_runtime_update -> | snd_pcm_period_elapsed ->
>> dpcm_be_disconnect(old) -> | snd_pcm_update_hw_ptr0 ->
>> __________________________ | xrun ->
>> | | | snd_pcm_stop ->
>> |list_del(&dpcm->list_be) | | dpcm_fe_dai_trigger ->
>> |list_del(&dpcm->list_fe) | | dpcm_be_dai_trigger ->
>> |kfree(dpcm); | | list_for_each_entry(dpcm..
>> |_________________________| |
>>
>> On CPU1, list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
>> will get dpcm and corresponding be, but there is no protection against the
>> dpcm_be_disconnect on cpu0. Related dpcm for the BE may be invalid/freed
>> when cpu1 tries to access it.
>
>> Should we require user space to make sure audio transfer ends before closing
>> audio path to avoid such issue? I'm not sure if I missed anything or used it
>> wrongly.
>
> Well, it should do that in general if it wants to make sure that the
> audio actually gets played but the kernel should protect against this.
> We should be holding a lock whenever we update the lists.
Thanks a lot for your suggestion! Firstly we'll ask user space app to
apply this rule currently to avoid such issue.
Currently it holds card->mutex in mutex_lock_nested whenever the list is
updated. Here list_for_each_entry in snd_pcm_stop may run in interrupt
context(the bottom half of tasklet), so it can not use this mutex
simply. Is there any other way to protect it?
>
>> Thanks in advance!
>> --
>>
>> Best Regards
>> Qiao
>>
--
Best Regards
Qiao
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [question about DPCM] dpcm_be_disconnect race condition
2014-08-28 2:07 ` Qiao Zhou
@ 2014-08-28 8:58 ` Mark Brown
0 siblings, 0 replies; 3+ messages in thread
From: Mark Brown @ 2014-08-28 8:58 UTC (permalink / raw)
To: Qiao Zhou
Cc: tiwai@suse.de, Xin Qian, alsa-devel@alsa-project.org,
Liam Girdwood
[-- Attachment #1.1: Type: text/plain, Size: 1021 bytes --]
On Thu, Aug 28, 2014 at 10:07:14AM +0800, Qiao Zhou wrote:
> On 08/28/2014 02:52 AM, Mark Brown wrote:
> >On Wed, Aug 27, 2014 at 04:15:00PM +0800, Qiao Zhou wrote:
> >Well, it should do that in general if it wants to make sure that the
> >audio actually gets played but the kernel should protect against this.
> >We should be holding a lock whenever we update the lists.
> Thanks a lot for your suggestion! Firstly we'll ask user space app to apply
> this rule currently to avoid such issue.
> Currently it holds card->mutex in mutex_lock_nested whenever the list is
> updated. Here list_for_each_entry in snd_pcm_stop may run in interrupt
> context(the bottom half of tasklet), so it can not use this mutex simply. Is
> there any other way to protect it?
Right, that's a problem. We'd need to either have a finer grained spin
lock (which we'd doubtless end up needing to hold for far too long so
probably won't work) or defer the list update to a workqueue or other
non-interrupt context which gets tricky. Hrm...
[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-08-28 8:58 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <53FD9384.3020501@marvell.com>
2014-08-27 18:52 ` [question about DPCM] dpcm_be_disconnect race condition Mark Brown
2014-08-28 2:07 ` Qiao Zhou
2014-08-28 8:58 ` Mark Brown
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.