-
Notifications
You must be signed in to change notification settings - Fork 140
Fix allocation of link dma channels #895
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
Fix allocation of link dma channels #895
Conversation
plbossart
left a comment
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.
Thanks @ranj063. This PR has the main benefit of yanking all the code I didn't like and the ASoC API abuse, but the parts on the locked/opened flags are a bit unclear, and the ABI change does not seem necessary.
sound/soc/sof/intel/hda-dai.c
Outdated
| case SNDRV_PCM_TRIGGER_SUSPEND: | ||
| case SNDRV_PCM_TRIGGER_STOP: | ||
| if (stream.opened) | ||
| stream.opened = 0; |
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.
We directly handle internals of the hdac library but those assignments are only taken into account when there is an explicit call to hdac_ext_xyz(), so it's quite hard to follow the state machine 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.
@plbossart understood. I probably need to add some more comments to why and how this is done here. Will address in v2
@plbossart I changed the ABI because if the kernel allocates link DMA channels dynamically, it is not compatible with the older version of the FW which require statically allocated channels and vice-versa. But @lgirdwood commented that he'd like to address the compatibility by having the FW advertise which allocation scheme it uses and the driver can switch to that. This means that we wont be able to remove all the code which abuses the get_channel_map() API. What would be your take on it? |
Removing that code solves a long standing issue of abusing the ASoC APIs for HDaudio/iDISP specific stuff, keeping it is not really a goal.. I would err on the side of claiming HDaudio/iDISP never fully worked, and the recommended programming sequence was only communicated recently to the SOF team, and that this is not really a compatibility break but a redesign to deal with how the hardware actually works. We can require all users of Hdaudio/iDISP to update the firmware at this point, and in practice they will update based on new releases already planned. As long as 1.3 includes that release we don't really need to worry. I hate to break compatibility but here we are enabling a feature. As discussed I would put a pretend minor ABI change to report that the firmware needs to be upgraded to work around this known incompatibility when HDaudio is used. |
7fad818 to
4abf19c
Compare
|
@plbossart PR updated now. |
lgirdwood
left a comment
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've mentioned the ABI as this will be the second PR (after @bardliao timestamp) where we can align the FW/kernel after the recent mis-alignment. See https://github.com/orgs/thesofproject/projects/2 for details on MINOR features (and the delta)
include/uapi/sound/sof/abi.h
Outdated
| /* SOF ABI version major, minor and patch numbers */ | ||
| #define SOF_ABI_MAJOR 3 | ||
| #define SOF_ABI_MINOR 5 | ||
| #define SOF_ABI_MINOR 6 |
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.
MINOR 8
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.
@lgirdwood fixed now
4abf19c to
56d6814
Compare
RanderWang
left a comment
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.
So in this commit, you need to send ipc message to FW ? I don't find it.
|
Correct two cases: It should be Link hw_params -> Host hw_params -> Host START -> Link START Here, host DMA channel would be assigned in host pcm open (hda_dsp_pcm_open). |
|
I am confused: The flags: stream->opened and locked are set in start or stop cases, but the dma channel allocation is done at pcm_open for host and hw_param for BE. How does it work? The host dma and link dma have been allocated before trigger_start, right ? |
include/sound/sof/dai-intel.h
Outdated
| struct sof_ipc_dai_hda_params { | ||
| struct sof_ipc_hdr hdr; | ||
| uint32_t link_dma_ch; | ||
| uint32_t reserved[8]; |
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.
It should be added in sof_ipc_pcm_params for you assign link dma channel in hw_param.
The sof_ipc_dai_hda_params is for dai_link loading
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.
@RanderWang I suppose i didnt do that good of a job explaining things. Because of our requirement to couple before setting the HDA format, the host DMA stream tag and the link DMA stream tag will always need to be the same. So, I only send one stream tag to the DSP during host pcm hw_params. Because of the way, the link DMA tags are "reserved", the link dma channel assigned during link hw_params will always be the same as host dma stream tag.
Please give this PR a try and test all kinds of scenarios you think could be broken. That's really what I am doing too. @fredoh9 and myself have been testing a few kinds of concurrent use cases and havent been able to see any issues with our hda generic topology so far.
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.
yes, I just said in FW patch. two cases:
(1) for two FEs share one BE, the param would be called two times and one of them the tag should be different.
(2) For some streams with only BE like tone generator, there is no host stream
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.
@RanderWang when the hw_params will be the called the second time, we will ignore the channel as it will not be INVALID at that point.
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.
yes, I get it.
|
And the host stream tag should be different in multi-thread cases. For this sequence, the tag should be different. The key idea is: the open-hw_param-start is not a atomic operation |
|
@RanderWang I'm going to have to challenge you to prove my theory wrong here. Take a look at Line 933 in 1071743
pcm_hw_params() is locked before performing fe hw_params and the be hw_params. So what you're describing in the multi-threaded case isnt possible. But like I said, this is my theory. Please do the needful to prove me wrong. |
|
this lock only protects BE hw_param, not open function for FE, right ? FE allocates host dma in hda_dsp_pcm_open, which is not protected by this lock |
|
Take it easy. What I asked is discussed with Pierre last year. I spent a least one month. |
@RanderWang we're talking about discussions that are stale. What you discussed with Pierre last year was before you implemented the programming sequence to couple/decouple while setting the DMA format. Lets not go down a rat hole. Lets stick with the new information and try to make progress. This change is complicated and is likely not the final solution. But our current solution is severely compromised for concurrent use cases. So lets try to take one step at a time and try to fix the 1:1 FE <-> BE topologies. |
really? did you take a look at this? Line 501 in 1071743
|
|
you don't got my idea. Each open and hw_param function is protected by lock, but the lock is released after open and acquired when hw_param is invoked ? So between open and hw_param, there is no lock. |
|
And you could refine our driver, allocate host dma channel in hw_param for FE, not in open function. |
|
@ranj063 This PR would cause an debugfs copying issue, when I tried to copy /sys/kernel/debug/sof/dsp to other directory, it couldn't be interrupted by any key, even though 'ctrl + c', and the system also hung. the same operation does't hung system based on daily build version. please help to check it. Reproduce Steps |
@stevyan which platform did this happen on? CML or all of them? |
@RanderWang yes, thats what I am thinking too. Let me change the PR to do host dma stream tag assignment in hw_params. |
yes, I agree with you at this case. One concern is that: do you plan to only support N:1 (N >= 1) for this PR ? As I know, you could archive this without changing ABI or IPC, and your change is ready in FW. Another issue is that: stream should be protected by lock, just like hda_dsp_stream_get. I strongly recommend you improve hda_dsp_stream_get function, and move stream->locked setting to this function for: (2) you don't need to protect stream with lock, this function does it. (3) you could allocate host dma & link dma and reserve corresponding dma channel in hw_params, which is protected by ASoC lock, so there is no multi-thread issue. If the allocation is done in hw_params but reservation of dma is done in trigger function, the reserved channel maybe allocated by other pcm in other thread before this thread invokes trigger function. (correct me if I misunderstand) (4) it is easy to support 1:N case with this change, because all the change should be in hda_dsp_stream_get function. one basic idea: BE hw_params would be called before FE hw_params by ASoC. |
plbossart
left a comment
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.
Thanks @ranj063 minor newlines issues but otherwise we are good to go. Can you update and I'll merge tomorrow after one CI round?
sound/soc/sof/topology.c
Outdated
| #include "ops.h" | ||
|
|
||
| #define COMP_ID_UNASSIGNED 0xffffffff | ||
|
|
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.
different 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.
@plbossat did you mean to separate out the topology parts into a separate 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.
no, move the newline somewhere else
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.
@plbossart ahh ok. I've removed it. I dont know how it sneaked in.
The recommended HDA HW programming sequence for setting the DMA format requires that the link DMA and host DMA channels be coupled before setting the format. This change means that host DMA or link DMA channels be reserved even if only one is used. Statically assigned link DMA channels would mean that all the corresponding host DMA channels will need to be reserved, leaving only a few channels available at run-time. So, the suggestion here is to switch to dynamically assigning both host DMA channels and link DMA channels are run-time. The host DMA channel is assigned when the pcm is opened as before. While choosing the link DMA channel, if the host DMA channel corresponding to the link DMA channel is already taken, the proposed method checks to make sure that the BE is connected to the FE that has been assigned this host DMA channel. Once the link DMA channel is assigned, an IPC is sent to the DSP to set the link DMA channel. The link DMA channel is freed during hw_free() and also in the SUSPEND trigger callback. It will be re-assigned when hw_params are set upon resume. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Due to the HW programming sequence requirement that the host and link DMA channels need to be coupled/decoupled during pcm hw_params, the host DMA channel corresponding to the link DMA channel in use for hostless streams needs to be reserved. This is achieved by adding a host_reserved flag in the sof_intel_hda_stream structure which is checked when assigning a host DMA channel. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
…pend Paused streams do not get suspended when the system enters S3. So, clear and release link DMA channel for such streams in the hda_dsp_set_hw_params_upon_resume() callback. Also, invalidate the link DMA channel in the DAI config before restoring the dai config upon resume. Also, modify the signature for the set_hw_params_upon_resume() op to return an int. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Host and link DMA are decoupled during FE hw_params. So, they must be coupled in hw_free if the link DMA channel is idle. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
b249c76 to
c1574ab
Compare
plbossart
left a comment
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.
Thanks @ranj063 looks good to me. Need a second approver to merge!
keyonjie
left a comment
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.
Good to go for me, it is fundamental change for link dma support, let's go with incremental fixes if issues exposed on it.
|
Alright let's merge and test. Thanks @ranj063 |
|
@xiulipan @wenqingfu the CI is completely in the weeds. The build fail is in the make bindebpkg phase. |
|
The compilation works fine on my machine so I will go ahead and merge. |
|
@plbossart @ranj063 |
|
On 5/29/19 4:06 AM, xiulipan wrote:
@plbossart <https://github.com/plbossart> @ranj063
<https://github.com/ranj063>
The build fail is because there is a warnging and we treat warning as
error in Travis.
|sound/soc/sof/intel/hda-dsp.c: In function
‘hda_dsp_set_hw_params_upon_resume’:
sound/soc/sof/intel/hda-dsp.c:469:6: error: variable ‘stream_tag’ set
but not used [-Werror=unused-but-set-variable] int stream_tag;
^~~~~~~~~~ cc1: all warnings being treated as errors |
Ah yes. With CI completely gone yesterday we didn't see this. Will send
a PR to quickly fix this.
|
The recommended HDA HW programming sequence for setting the DMA format requires that the link DMA and host DMA channels be coupled before setting the format. This change means that host DMA or link DMA channels be reserved even if only one is used.
Statically assigned link DMA channels would mean that all the corresponding host DMA channels will need to be reserved, leaving only a few channels available at run-time. So, the suggestion here is to switch to dynamically assigning both host DMA channels and link DMA channels are run-time.
The host DMA channel is assigned when the pcm is opened as before. While choosing the link DMA channel, if the host DMA channel corresponding to the link DMA channel is already taken, the proposed method checks to make sure that the BE is connected to the FE that has been assigned this host DMA channel. For hostless streams, the host DMA channel is marked as opened to ensure it isn't assigned to another stream. After assigning the link DMA channel, a DAI_CONFIG IPC is sent to the FW to set the chosen link DMA channel.
This change should support N:M FE <->BE configurations as well.
The corresponding FW change for this PR is thesofproject/sof#1354
Tested on UP2 so far. Further testing in progress.