-
Notifications
You must be signed in to change notification settings - Fork 132
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ASoC: SOF: disable dma trace in s0ix #3099
Conversation
@libinyang What bug/issue is this related to? Also this patch ignores the existing code where we added the ability to enable the trace in S0ix, see sound/soc/sof/intel/hda-dsp.c static bool hda_enable_trace_D0I3_S0;
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG)
module_param_named(enable_trace_D0I3_S0, hda_enable_trace_D0I3_S0, bool, 0444);
MODULE_PARM_DESC(enable_trace_D0I3_S0,
"SOF HDA enable trace when the DSP is in D0I3 in S0");
#endif
/*
* Trace DMA need to be disabled when the DSP enters
* D0I3 for S0Ix suspend, but it can be kept enabled
* when the DSP enters D0I3 while the system is in S0
* for debug purpose.
*/
if (!sdev->dtrace_is_supported ||
!hda_enable_trace_D0I3_S0 ||
sdev->system_suspend_target != SOF_SUSPEND_NONE)
flags = HDA_PM_NO_DMA_TRACE; I am not sure what to make of your proposal... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic to call trigger stop upon d0ix entry looks ok, but I think the patch needs some work before merging. See comments inline.
sound/soc/sof/pm.c
Outdated
dev_err(sdev->dev, | ||
"error: snd_sof_dma_trace_trigger: stop: %d\n", ret); | ||
else | ||
sdev->dtrace_is_enabled = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think L216-221 code would be better moved to trace.c and manage all logic around "sdev->dtrace_is_enabled" in trace.c and just have simple function calls here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I will do it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@libinyang Sounds good to me. Maybe spin a version for review?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@libinyang Sounds good to me. Maybe spin a version for review?
OK. Thanks.
sound/soc/sof/pm.c
Outdated
dev_err(sdev->dev, | ||
"error: snd_sof_dma_trace_trigger: start: %d\n", ret); | ||
} else | ||
sdev->dtrace_is_enabled = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as below, the error print and modifying dtrace_is_enabled would be better handled in trace.c and just have a simple function call here.
@plbossart wrote:
My take: this is not about enabling trace in S0ix, but rather taking additional steps to disable trace (trigger stop on the trace DMA on host side), to ensure system really can enter S0ix. On older platforms this was not needed (hw ignored the state end went to S0ix, but that is no longer the case). |
Ah yes, sorry. The parameter is to keep the trace in S0, I read sideways. Still, I am worried about this trigger. I don't think this should be in generic code as well, but instead part of the sequence where we write the D0I3C_I3 register. Otherwise, there's a risk of firmware thinking it can start traces but the DMA is not enabled. /* Set flags and register value for D0 target substate */
if (target_state->substate == SOF_HDA_DSP_PM_D0I3) {
value = SOF_HDA_VS_D0I3C_I3;
/*
* Trace DMA need to be disabled when the DSP enters
* D0I3 for S0Ix suspend, but it can be kept enabled
* when the DSP enters D0I3 while the system is in S0
* for debug purpose.
*/
if (!sdev->dtrace_is_supported ||
!hda_enable_trace_D0I3_S0 ||
sdev->system_suspend_target != SOF_SUSPEND_NONE)
flags = HDA_PM_NO_DMA_TRACE;
} else {
/* prevent power gating in D0I0 */
flags = HDA_PM_PPG;
}
/* update D0I3C register */
ret = hda_dsp_update_d0i3c_register(sdev, value);
if (ret < 0)
return ret;
/*
* Notify the DSP of the state change.
* If this IPC fails, revert the D0I3C register update in order
* to prevent partial state change.
*/
ret = hda_dsp_send_pm_gate_ipc(sdev, flags);
if (ret < 0) {
dev_err(sdev->dev,
"error: PM_GATE ipc error %d\n", ret);
goto revert;
} I would disable the DMA after the D0i3 transition and conversely restore it prior to the D0 transition. That way we never have a case where the firmware is blocked by the kernel. |
@plbossart @kv2019i Thanks for the review and comments. I took vacation last week and sorry for the delay reply. |
@plbossart Thanks for the suggestion. Your suggested sequence seems more reasonable. I will update the patch. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is better to release trace unconditionally during system suspend irrespctive of the target state.
Yes, I did think of this releasing dma trace solution at first. I'm OK with this solution. Releasing dma trace is the simplest way. What I concern is there is an IPC and some extra register setting to re-init the dma trace which may impact the resume performance? @plbossart @kv2019i What's your opinion? |
@plbossart @kv2019i this is my alternate proposal (not tested @libinyang would need to confirm if it has the same outcome as his patch)
|
This patch can't be such simple as we still need release the resource in FW. At lease we need send one or two extra IPCs to FW to trigger stop the DMA and release the DMA resource. |
@libinyang can you please be precise? do you mean we need 1 extra IPC or 2 extra IPCs? And which ones are those? release trace should already be sending the stop IPC. its good enough even for D3, what else is it missing? |
@ranj063 Which stop IPC do you mean? I didn't find the IPC. I only can find the pm gate IPC, which only stop the trace_work in firmware. But I think we still need set the corresponding dma registers to the correct values after releasing DMA. After stopping the dma, we need to send an IPC to release the resource in firmware. So next time we initialize the dma trace, we can re-allocate the dma channel and other resources in firmware code |
@libinyang have you tried my patch? are you still seeing the problem with it? I am confused by your questions. snd_sof_release_trace() takes care of sending the STOP IPC already and frees the resources. Doing this unconditionally for all system suspend targets is enough IMHO. Could you please try my patch and let me know if it works or not? |
@ranj063 Last Friday we had team building and I didn't have time to try and analyze. Here is the result.
Below is the dmesg and sof-logger errror. sof-logger: And I add a patch to trace the resource release:
I can find the resource is not released until the next dma trace initialization, it met error then release the resource. [ 147.708327] ( 147.708328) c0 dma-trace src/trace/dma-trace.c:337 ERROR FW ABI 0x3012001 DBG ABI 0x5003000 tag v1.8-rc2-41-g263ab4ab16a4-dirty src hash 0x298ff932 (ldc hash 0x298ff932) [ 5919185.962709] ( 5919018.000000) c0 kpb 11.55 src/audio/kpb.c:408 ERROR kpb_params(): kpb has been already configured. [ 118183249.001736] ( 153.177078) c0 dma-trace src/trace/dma-trace.c:337 ERROR FW ABI 0x3012001 DBG ABI 0x5003000 tag v1.8-rc2-41-g263ab4ab16a4-dirty src hash 0x298ff932 (ldc hash 0x298ff932) [ 118183339.730899] ( 36.302082) c0 ipc src/ipc/handler-ipc3.c:746 ERROR ipc: failed to enable trace -22 |
If we are still trying to release dma trace all the time in sof_suspend(), we should use IPC to notify the firmware to release the resource, either with new IPC or in the pm gate IPC. And also we should have some change in FW code. |
@ranj063 @libinyang Hmm, it seems the IPC interface doesn't support disable trace. I.e. we only have a message to set up DMA trace (SOF_IPC_TRACE_DMA_PARAMS) but only way to disable is to power-off the DSP. So @ranj063 your patch won't work when DSP remains in D0i3. I'd go with @libinyang your original approach of adding TRIG_START/STOP (but address the remaining comments). Ok to you @ranj063 ? |
sound/soc/sof/pm.c
Outdated
@@ -119,8 +119,15 @@ static int sof_resume(struct device *dev, bool runtime_resume) | |||
* D0 substate. | |||
*/ | |||
if (!runtime_resume && sof_ops(sdev)->set_power_state && | |||
old_state == SOF_DSP_PM_D0) | |||
old_state == SOF_DSP_PM_D0) { | |||
ret = snd_sof_dma_trace_trigger(sdev, SNDRV_PCM_TRIGGER_START); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not check if sdev->dtrace_is_enabled is already true before triggering again? It could have failed during suspend right? And then this would mean you don't need to do the check for it again in the platform-specific trigger as above in hda-trace.c
ack @kv2019i lets go with this approach but I think it needs a minor adjustment in the placement of the check for trace_enabled |
be01823
to
cbedd8b
Compare
patch updated. Change log from v1:
|
sound/soc/sof/ops.h
Outdated
if (!sdev->dtrace_is_supported) | ||
return 0; | ||
|
||
/* FIXME: return 0 or return -EINVAL ? */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trace_trigger is an optional op, so return 0 please and remove FIXME and can you please combine the 2 checks for dtrace_is_supported and trace_trigger in 1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK
sound/soc/sof/ops.h
Outdated
|
||
switch (cmd) { | ||
case SNDRV_PCM_TRIGGER_START: | ||
/* FIXME: return 0 when dtrace_is_enabled? */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is this fixme intended for? whether you should return 0 or error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean whether we should return other value instead of "0" to tell the caller dma trace is already enabled. I will remove this comment.
sound/soc/sof/ops.h
Outdated
ret = sof_ops(sdev)->trace_trigger(sdev, cmd); | ||
if (ret < 0) { | ||
dev_err(sdev->dev, | ||
"error: snd_sof_dma_trace_trigger: start: %d\n", ret); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove err prefix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK. Yes, removing the "error" is better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hold on, although not a fan, @ranj063 I think we still generally add "error: "to dev_errs . @plbossart @ujfalusi have we changed policy on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kv2019i we want to remove "error:" since it makes no sense, but we will do it gradually through new changes to avoid backport issues. So were we should remove the "error:" on line 409.
sound/soc/sof/ops.h
Outdated
"error: snd_sof_dma_trace_trigger: start: %d\n", ret); | ||
} else { | ||
sdev->dtrace_is_enabled = true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and remove unnecessary braces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK
sound/soc/sof/ops.h
Outdated
"error: snd_sof_dma_trace_trigger: stop: %d\n", ret); | ||
} else { | ||
sdev->dtrace_is_enabled = false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same 2 comments as above here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me to have the logic in ops. I'd move this to ops.c though. This is not performance sensitive, so no need to have the code in ops.h.
sound/soc/sof/ops.h
Outdated
ret = sof_ops(sdev)->trace_trigger(sdev, cmd); | ||
if (ret < 0) { | ||
dev_err(sdev->dev, | ||
"error: snd_sof_dma_trace_trigger: start: %d\n", ret); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hold on, although not a fan, @ranj063 I think we still generally add "error: "to dev_errs . @plbossart @ujfalusi have we changed policy on this?
cbedd8b
to
ef3d091
Compare
sound/soc/sof/pm.c
Outdated
@@ -238,6 +242,9 @@ static int sof_suspend(struct device *dev, bool runtime_suspend) | |||
|
|||
suspend: | |||
|
|||
/* release trace */ | |||
snd_sof_release_trace(sdev, target_state == SOF_DSP_PM_D0 ? true : false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After giving this a thought I think we should aim a more generic approach by passing the target_state
directly and let the dtrace code to decipher from there.
But the SOF_DSP_PM_D0 is not really the state we are entering (from SOF_DSP_PM_D0), but it is SOF_DSP_PM_D0:SOF_HDA_DSP_PM_D0I3, so is is more like SOF_DSP_PM_D0_LP.
Basically we will tell the dtrace that we are suspending to the given level:
SOF_DSP_PM_D3 - DSP is going to be off
SOF_DSP_PM_D0 - DSP remains on
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After giving this a thought I think we should aim a more generic approach by passing the
target_state
directly and let the dtrace code to decipher from there.
But the SOF_DSP_PM_D0 is not really the state we are entering (from SOF_DSP_PM_D0), but it is SOF_DSP_PM_D0:SOF_HDA_DSP_PM_D0I3, so is is more like SOF_DSP_PM_D0_LP.Basically we will tell the dtrace that we are suspending to the given level:
SOF_DSP_PM_D3 - DSP is going to be off
SOF_DSP_PM_D0 - DSP remains on
@ujfalusi This should be another topic beyond this PR, which may impact the dtrace behavior and policy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@libinyang, the policy is:
if the DSP is going off then free up all resources and on resume set up everything from scratch
if the DSP is not going to be off then stop the host DMA and on resume only restart the host DMA
Doing the target_state == SOF_DSP_PM_D0 ? true : false
in pm.c
or in the trace.c
does not change the policy and behavior especially that this PR is changing it in the first place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ujfalusi I mean the policy whether we should keep trace.c
as simple as possible and won't take the responsibility to decide trigger stop or trigger start.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The trace is moving out as a separate driver and it will have to make it's own decisions anyways.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and it is not trigger start or stop question. It is suspend and resume question. Are suspending to a level where the DSP is off or are we keeping it on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The trace is moving out as a separate driver and it will have to make it's own decisions anyways.
After reading the email you sent, it seems I understand your ideas now. Let's talk more in the weekly meeting.
I'm a bit puzzled on under which scenario this PR is going to have effect. Afaik if we do a system suspend (either S3 or s2idle via /sys/pm/state) user space is going to frozen and audio would be stopped, we don't set I'm sure I got this wrong as there would not have been this PR... |
WoV is working in this case.
No, for deep buffer and WoV audio, it still works. trigger suspend will be called but trigger resume won't based on my test.
|
Currently DMA trace has only 2 states: enabled or disabled. However DMA trace may have more states. For example, enabled but not started. This patch refines the dma trace to provide a mechanism to store more states than enabled/disabled and adds SOF_DTRACE_STOPPED state. Peter Ujfalusi <[email protected]> Signed-off-by: Libin Yang <[email protected]>
When system enters s0ix, the dma trace won't be used. Otherwise, the DMA will access the host memory, which will prevent entering S0ix. Driver has notified firmware not to send message through dma trace. Let's also trigger stop dma trace in driver side. Signed-off-by: Libin Yang <[email protected]>
228553c
to
dc933f6
Compare
@libinyang lets pause this PR for a bit until I fix the HD-DMA sequence for DMA stop in the kernel and the firmware. Sorry for the trouble! |
@ranj063 Does this PR conflict with your patch? |
I dont know yet. I'm still deciding how to solve the problem I have with trace. So its better to see how it pans out before we make another change in trace. Please give me a day or two and I should have a PR open. This issue is lower priority compared to the HD-DMA programming fix |
@ranj063 Got it. Please let me know whether this PR is needed or not needed based on your latest solution. Thanks. |
@libinyang @ranj063 is this PR still relevant? |
no idea @plbossart . @libinyang was supposed to recheck after the HDA audio DMA patches were merged |
@plbossart @ranj063 Sorry for the delay reply. This bug is reproduced on ADL Chrome (TGL platform can't reproduce this bug, and ADL RVP platforms doesn't support s0ix well), which is using 5.10 kernel. As Ranjani said her DMA patches may impact on this PR. So I have to port Ranjani's patch to chrome kernel. But there is a big gap between chrome kenrel and SOF, and hard to me to back port it. So I'm waiting Chrome team to decide whether they will back port Ranjani's patch or not. @kv2019i has already ported Ranjani DMA patches for Chrome. ---- update ---- |
@libinyang is there an issue to track the problem? |
@plbossart The issue is tracked in #3034 and we have a suspicioun this is related to newer issue thesofproject/sof#5042 |
thanks @kv2019i so let's close this PR and submit a new one when we have a solution. |
I have confirmed that Ranjani's DMA patches can't fix the bug #3034. We still need this patch. I will submit a new one after the run_all test. |
Ack @libinyang and @ujfalusi , I was able to confirm the same. With stop-dma patches for both kernel and FW, including the dtrace dma free IPC, I can still reproduce. It would seem system does not enter S0ix in this case. |
I have applied all @kv2019i patches to Chrome and it doens't work. |
@libinyang @kv2019i I think we all know none of the HDA-DMA patches will help with the issue. When we enter D0i3, we do not stop trace and hence won't free it. I only asked to pause this PR because the fix will be slightly different with the HDA-DMA patches with the trace_free IPC. @libinyang please resend what's needed to fix the issue. |
But now we do not need to hack around to handle the hoat side only. We can stop and restart the firmware side as well. |
@libinyang, I know, I was saying that we now have a way to disable the dtrace in firmware which allows reconfiguration. One of the issue you have cited is that consequent dtrace enable fails and you needed to have workaround this. |
I found this PR can't work with the latest sof linux kernel. After applying this PR, it will block sof driver enter pm-runtime suspend on the latest sof linux kernel. I'm still debugging on it. |
A new patch is submitted: #3332 |
When system enters s0ix, the dma trace won't be used. Otherwise,
the DMA will access the host memory, which will prevent entering
S0ix. Driver has notified firmware not to send message through
dma trace. Let's also trigger stop dma trace in driver side.
Signed-off-by: Libin Yang [email protected]