Linux Sound subsystem development
 help / color / mirror / Atom feed
From: "Péter Ujfalusi" <peter.ujfalusi@linux.intel.com>
To: Takashi Iwai <tiwai@suse.de>
Cc: lgirdwood@gmail.com, broonie@kernel.org, tiwai@suse.com,
	perex@perex.cz, linux-sound@vger.kernel.org,
	kai.vehmanen@linux.intel.com, ranjani.sridharan@linux.intel.com,
	yung-chuan.liao@linux.intel.com, pierre-louis.bossart@linux.dev,
	liam.r.girdwood@intel.com
Subject: Re: [RFC] ASoC: SOF: sof-pcm/pm: Stop paused streams before the system suspend
Date: Tue, 1 Apr 2025 15:20:14 +0300	[thread overview]
Message-ID: <52a4cc86-8982-48a5-ad4c-35c8d6d52cde@linux.intel.com> (raw)
In-Reply-To: <648a5d66-6e68-4287-9dce-20c2a2541e5c@linux.intel.com>



On 01/04/2025 14:28, Péter Ujfalusi wrote:
> 
> 
> On 31/03/2025 14:09, Takashi Iwai wrote:
>> On Mon, 31 Mar 2025 12:56:31 +0200,
>> Peter Ujfalusi wrote:
>>>
>>> Paused streams will not receive a suspend trigger, they will be marked by
>>> ALSA core as suspended and it's state is saved.
>>> Since the pause stream is not in a fully stopped state, for example DMA
>>> might be still enabled (just the trigger source is removed/disabled) we
>>> need to make sure that the hardware is ready to handle the suspend.
>>>
>>> This involves a bit more than just stopping a DMA since we also need to
>>> communicate with the firmware in a delicate sequence to follow IP
>>> programming flows.
>>> To make things a bit more challenging, these flows are different between
>>> IPC versions due to the fact that they use different messages to implement
>>> the same functionality.
>>>
>>> To avoid adding yet another path, callbacks and sequencing for handling the
>>> corner case of suspending while a stream is paused, and do this for each
>>> IPC versions and platforms, we can move the stream back to running just to
>>> put it to stopped state.
>>>
>>> Explanation of the change:
>>> Streams moved to SUSPENDED state from PAUSED without trigger. If a stream
>>> does not support RESUME then on system resume the RESUME trigger is not
>>> sent, the stream's state and suspended_state remains untouched.
>>> When the user space releases the pause then the core will reject this
>>> because the state of the stream is _not_ PAUSED, it is still SUSPENDED.
>>>
>>> From this point user space will do the normal (hw_params) prepare and
>>> START, PAUSE_RELEASE trigger will not be sent by the core after the
>>> system has resumed.
>>>
>>> Link: https://github.com/thesofproject/linux/issues/5035
>>> Link: https://github.com/thesofproject/linux/issues/5341
>>> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
>>> ---
>>> Hi,
>>>
>>> Please see the problem statement and details of the issue in the commit
>>> message.
>>>
>>> I'm not sure if this should be done in ALSA+ASoC level instead. My fear
>>> is that this is changing how things has been working since almost
>>> forever and it really puzzles me why it is not affecting other drivers.
>>> It is true that in SOF the PAUSED state is not equal to STOPED while
>>> it might be so for other vendors (it is for TI stuff for sure).
>>>
>>> The main point is that when we do a system suspend and a stream is in
>>> PAUSED state, it will not be triggered (PAUSED == SUSPENDED/STOPPED
>>> assumption?). On resume, if the platform is not supporting RESUME then
>>> nothing will be done for the PAUSED stream, but a PAUSE_RELEASE will
>>> fail and all sorts of state machine assumption will break in SOF/ASoC
>>> stack.
>>>
>>> I have a PR open for quite long [1] but we would like to find the best
>>> solution for us and possibly for others facing the same issue as well.
>>>
>>> [1] https://github.com/thesofproject/linux/pull/5058
>>
>> IMO, this kind of thing should be handled in ALSA core side.
>> If we want to avoid possible breakage, a flag can be introduced and
>> perform this conditionally, too.  It'll become a bit complex, but
>> that's because of the subtle hardware behavior differences,
>> unfortunately.
> 
> I had hard time to define that flag to act upon for months ;)
> 
> It is something of a mix of conditions that needs to be present and
> _might_ not really need a new flag:
> 
> The PCM device must support SNDRV_PCM_INFO_PAUSE and must not support
> SNDRV_PCM_INFO_RESUME.
> Given that ALSA core will not trigger the PAUSED streams on suspend,
> they just moved to SUSPENDED.
> On resume the RESUME is going to be skipped as well as it is not
> supported, the PAUSED stream remains SUSPENDED.
> If the RESUME is supported then the driver will receive the trigger and
> _might_ be able to move things around to match the paused state it was
> before suspend.
> 
> This patch in a way plays with these rules knowing that on resume the
> paused stream is going to fail to release and we will go to a new start,
> so internally it would bluntly stops anything which is paused, they will
> never going to PAUSE_RELEASE, they will be started w/o the driver's
> knowledge of a skipped pause release.
> 
> What I'm not sure is how this can be done legitimately in core. Move the
> stream from PAUSED to STOPPED without user space knowing it? So after
> resume the it thinks that the stream is paused, but the kernel has moved
> it to stopped?
> 
> In SOF we need a bit higher level triggers to have the delicate
> sequencing right for the BE/FE and for the IPC versions.
> 
> I think this is where I thought that this is a bit more complicated than
> just add a flag and do the trigger.

Having said all of this, the following small diff works well with SOF
stack, for aplay this is fine at least ;)

diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 6c2b6a62d9d2..6d8389642e37 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1694,8 +1694,14 @@ static int snd_pcm_do_suspend(struct
snd_pcm_substream *substream,
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (runtime->trigger_master != substream)
 		return 0;
-	if (! snd_pcm_running(substream))
-		return 0;
+	if (! snd_pcm_running(substream)) {
+		if (runtime->info & SNDRV_PCM_INFO_RESUME ||
+		    runtime->state != SNDRV_PCM_STATE_PAUSED)
+			return 0;
+
+		/* release the paused stream to suspend */
+		snd_pcm_pause(substream, false);
+	}
 	substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND);
 	runtime->stop_operating = true;
 	return 0; /* suspend unconditionally */

So, if the PCM device does not support resuming, then release the pause
before going the suspend.

-- 
Péter


  reply	other threads:[~2025-04-01 12:19 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-31 10:56 [RFC] ASoC: SOF: sof-pcm/pm: Stop paused streams before the system suspend Peter Ujfalusi
2025-03-31 11:09 ` Takashi Iwai
2025-04-01 11:28   ` Péter Ujfalusi
2025-04-01 12:20     ` Péter Ujfalusi [this message]
2025-04-01 12:40       ` Takashi Iwai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=52a4cc86-8982-48a5-ad4c-35c8d6d52cde@linux.intel.com \
    --to=peter.ujfalusi@linux.intel.com \
    --cc=broonie@kernel.org \
    --cc=kai.vehmanen@linux.intel.com \
    --cc=lgirdwood@gmail.com \
    --cc=liam.r.girdwood@intel.com \
    --cc=linux-sound@vger.kernel.org \
    --cc=perex@perex.cz \
    --cc=pierre-louis.bossart@linux.dev \
    --cc=ranjani.sridharan@linux.intel.com \
    --cc=tiwai@suse.com \
    --cc=tiwai@suse.de \
    --cc=yung-chuan.liao@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox