* 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.