-
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
SOF client support (auxiliary bus) #3007
SOF client support (auxiliary bus) #3007
Conversation
cd2d70e
to
13f2d81
Compare
changes since v1:
|
Note: The checkpatch warnings are all about new, renamed files versus MAINTAINERS file. |
if (ret < 0) | ||
goto free_desc; | ||
} else { | ||
break; |
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.
could just do
if (remaining <= 0)
break;
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.
True, but my intention was to go without any functional changes, this is coming from the merged two sof/probe.c and sof/compress.c file.
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.
let's add @lyakh's suggestion in a follow-up 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.
Can we push the following commits to a cleanup PR?
ASoC: SOF: ipc: Add probe message logging to ipc_log_header()
ASoC: SOF: pcm: Remove non existent CONFIG_SND_SOC_SOF_COMPRESS refer…
ASoC: SOF: compress: move and export sof_probe_compr_ops
ASoC: SOF: probe: Merge and clean up the probe and compress files
ASoC: SOF: intel: Rename hda-compress.c to hda-probes.c
That would make the rest easier to review.
@plbossart, yes, I think we can do that. I have re-arranged the commits in my wip branch as per your suggestion and the PR is created: #3014 |
I have a generic file naming convention question. We could also remove the @lgirdwood, @plbossart, @ranj063, @kv2019i, @lyakh what is your opinion on the matter? |
@ujfalusi No prefix has the advantage of saving the redundancy, while having a prefix makes "find" easier - I've just found 14 dev.c, 41 dma.c, 85 irq.c and 65 init.c in the kernel... So, personally I wouldn't mind using sof- prefix for all our files. As for type / function / variable names: the way I work having prefixes makes it easier. Try to find definition of |
13f2d81
to
6297911
Compare
Hi, Changes since v2:
|
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 any explanation for the across-the-board CI failures? Could this be an sof-test issue or is this a regression? |
@plbossart, I certainly don't have any explanation. The previous version (which was identical) had no such failures. Oh, I think this gives some clue for some of the test failures: If the probes are enabled then card0 is the probes card (with only compress capture), card1 is the audio card. If the probes are used by tests then the debugfs files are moved under |
I don't know why our CI requires the use of card0, they can filter based on the 'sof' prefix. another workaround is to use what distros use in alsa-base.conf
and
|
This will not work, ASoC does not have support for custom IDX, it will use SNDRV_DEFAULT_IDX1 unconditionally. There is no way to pass a custom idx, we have tried to get a support for it but the whole idea was rejected. fwiw this is the core patch: What works via module parameter is:
This will move the probes card to card3:
But this is static assignment and if a dynamic card got the slot 3 first then it will fail. We could try to add
Then let card drivers to deal with the |
The auxiliary bus provides suspend and resume callbacks for auxbus devices. They are used to notify child devices about the real hardware suspend resume operation so they can act if there is a need for them in case the real device's state changes. Signed-off-by: Peter Ujfalusi <[email protected]>
Clients might need to be aware of the SOF firmware version in case the IPC message format differs between revisions. Signed-off-by: Peter Ujfalusi <[email protected]>
The SOF core module (the device driver of the DSP) needs to be protected against removal when a client is active and needs the core to be present during it's active operation. sof_client_core_moduleget/put can be use by client drivers to manage the refcount on the core's module to prevent such a case. Signed-off-by: Peter Ujfalusi <[email protected]>
…race_prepare Pass the snd_dma_buffer pointer as parameter to hda_dsp_trace_prepare() function. Signed-off-by: Peter Ujfalusi <[email protected]>
The utils.c contains wrappers and implementation for accessing iomem mapped regions and a single unrelated function to create a compressed page table from snd_dma_buffer for firmware use. The later is used by the pcm and the trace code and it needs to be moved to a generic source/header for the client conversion to be possible. Signed-off-by: Peter Ujfalusi <[email protected]>
Move the IPC flood test code out from the debug file as separate SOF client driver. Based on the kernel configuration, the device registration for the new IPC flood test is going to happen in the core. With the separate client driver it is going to be possible to run multiple flood tests in parallel to increase the stress, the new Kconfig option can be used to select this (defaults to 1). In order to preserve backward compatibility with existing SW/scripts, the first IPC flood test's debugfs files have been linked to the old files. Signed-off-by: Ranjani Sridharan <[email protected]> Co-developed-by: Fred Oh <[email protected]> Signed-off-by: Fred Oh <[email protected]> Signed-off-by: Peter Ujfalusi <[email protected]>
Add additional protection for the debugfs file to make sure that it can not be removed while it is open. Signed-off-by: Peter Ujfalusi <[email protected]>
…ashed Do not allow the test to be started if the firmware is in crashed state. Signed-off-by: Peter Ujfalusi <[email protected]>
Add a new client driver for probes support and move all the probes-related code from the core to the client driver. The probes client driver registers a component driver with one CPU DAI driver for extraction and creates a new sound card with one DUMMY DAI link with a dummy codec that will be used for extracting audio data from specific points in the audio pipeline. The probes debugfs ops are based on the initial implementation by Cezary Rojewski and have been moved out of the SOF core into the client driver making it easier to maintain. This change will make it easier for the probes functionality to be added for all platforms without having the need to modify the existing(15+) machine drivers. Signed-off-by: Ranjani Sridharan <[email protected]> Signed-off-by: Peter Ujfalusi <[email protected]>
…upport Keep the probes support disabled by default and require module parameter to enable it explicitly as the probes usage is meant for developers only. This will avoid confusing users with the existence of a probes card with a compressed capture. Signed-off-by: Peter Ujfalusi <[email protected]>
Make sure that the core (the device driver for the DSP) can not be removed while the compress stream is running. Signed-off-by: Peter Ujfalusi <[email protected]>
…ashed Do not allow the compressed stream to be started if the firmware is in crashed state. Signed-off-by: Peter Ujfalusi <[email protected]>
Add a new client driver to implement the dma-trace functionality outside of the SOF core. This is optional for now, if the dma-trace client is enabled via the SND_SOC_SOF_HDA_DMA_TRACE kconfig option then the core's built in implementation is force disabled. Signed-off-by: Peter Ujfalusi <[email protected]>
i.MX is using dma-trace currently, make sure that the move to SOF client is not going to cause regression regarding to trace functionality. Signed-off-by: Peter Ujfalusi <[email protected]>
Switch to the SOF client version of the dma-trace. In order to not introduce regression the SND_SOC_SOF_DEBUG_ENABLE_FIRMWARE_TRACE is used to enable the new driver. Signed-off-by: Peter Ujfalusi <[email protected]>
…emoval Based on debugging the following issues were identified: if the snd_sof_dma_trace module is removed while the sof-logger keeps the trace file open: The module's remove will block on the debugfs_remove() until the sof-logger is stopped (w/ C-c). The sof_dfsentry_trace_read() will return and the debugfs file is removed, the module remove completes. Then the debugfs file's release callback got called but the file itself was already removed! The second issue is that while the client driver is loaded and sof-logger keeps the trace file open, the user can rmmod the parent driver for the DSP itself which will removes the SOF client devices and the same chain of events will happen. With this patch we protect the debugfs file from removal with the debugfs_file_get/put and we protect the parent device against removal while the module is in active use (the debugfs file is open). Signed-off-by: Peter Ujfalusi <[email protected]>
… crashed Do not allow the dma trace to be started if the firmware is in crashed state. Signed-off-by: Peter Ujfalusi <[email protected]>
The first count check and fixup against "buffer - lpos" can be removed as we will do the adjustment later against the "avail" in sof_dfsentry_trace_read() Signed-off-by: Peter Ujfalusi <[email protected]>
Reduce the number of long lines where it can be done in a clean way. Signed-off-by: Peter Ujfalusi <[email protected]>
Rename the "struct sof_ipc_client_data" to "struct sof_ipc_test_priv" Remove "error: " prefixing from error prints Rename the debugfs callbacks from sof_ipc_dfsentry_* to sof_ipc_test_dfs_* Long line wrapping cleanups Signed-off-by: Peter Ujfalusi <[email protected]>
Rename the debugfs callbacks to be somehow consistent Remove the "error: " prefix from error prints Signed-off-by: Peter Ujfalusi <[email protected]>
Rename the debugfs callbacks to be somehow consistent Signed-off-by: Peter Ujfalusi <[email protected]>
b7b40bf
to
3bd20bb
Compare
Changes since v14:
Opps:
Squashing patches is still postponed. |
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 see this series has grown to 32 commits and there are really a lot of opens left and right that could be IMHO addressed later.
What if e.g. we only enable IPC flood and probes for SOF clients? The DMA trace seems to be problematic but it doesn't really bring any value to move as a client, does it?
I think we should really look at realistic/smaller objectives and later on add more complicated scenarios/client types.
* Skip to platform-specific suspend if DSP is entering D0 or if it has | ||
* crashed | ||
*/ | ||
if (target_state == SOF_DSP_PM_D0 || sdev->fw_state == SOF_FW_CRASHED) |
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.
not sure about this one. In the 'sof_tear_down_pipelines' below we free some widgets. We wouldn't be able to restart with a clean slate out of D3 if we skip this part.
@ranj063 you'll have to chime in on this change,
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, you are right, my thinking was that since the firmware has crashed there is no point of trying to do a clean shutdown of it by sending messages. The firmware is in essence in a non initialized state. However I see that we do cleanup on the linux side and the path ignores IPC errors (which we will have).
I'll drop this change.
* firmware | ||
*/ | ||
if (sdev->fw_state == SOF_FW_CRASHED) | ||
return 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.
I don't understand this part either.
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.
If the firmware crashed we want the DSP to be hard reset. In this case we will not check if the platform would be capable of S0 state.
if (component->driver->module_get_upon_open == 1 && | ||
!try_module_get(component->dev->driver->owner)) | ||
ret = -ENODEV; | ||
|
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.
question: Why is this different from the regular components?
int snd_soc_component_module_get(struct snd_soc_component *component,
struct snd_pcm_substream *substream,
int upon_open)
{
int ret = 0;
if (component->driver->module_get_upon_open == !!upon_open &&
!try_module_get(component->dev->driver->owner))
ret = -ENODEV;
/* mark substream if succeeded */
if (ret == 0)
soc_component_mark_push(component, substream, module);
return soc_component_ret(component, 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.
The snd_soc_component_module_get()
is used for compressed only via snd_soc_component_module_get_when_probe()
wrapper where the substream
parameter is NULL. We can not use the snd_soc_component_module_get_when_open()
with compress stream as:
int snd_soc_component_module_get(struct snd_soc_component *component,
struct snd_pcm_substream *substream,
int upon_open);
expects snd_pcm_substream and not snd_compr_stream.
I should have used snd_soc_component_compr_module_get_when_open()
and snd_soc_component_compr_module_put_when_close()
to make it a cleaner
It might worth adding another mark to struct snd_soc_component
, like struct snd_compr_stream *mark_compr_module;
or
convert the struct snd_pcm_substream *mark_module;
to void *mark_module;
or
convert all marks to void *
IN the case of the later two the snd_soc_component_module_get() should have
void *for the substream, probably named as
mark`
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.
Should we try to send it upstream to get feedback which way this should be?
I have now the renamed version locally, introducing snd_soc_component_compr_module_get_when_open()
and snd_soc_component_compr_module_put_when_close()
We piggyback on compr_open
mark to manage the module_get/put to avoid introducing bigger changes for the framework and at the end the same thing is done for the normal components.
typedef void (*ipc_rx_callback)(struct snd_sof_dev *sdev, void *full_msg); | ||
|
||
static void ipc_trace_message(struct snd_sof_dev *sdev, void *full_msg); | ||
static void ipc_stream_message(struct snd_sof_dev *sdev, void *full_msg); |
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 don't get the concept of passing a void pointer without any indication of size to the client. How would they know how much data they can read from the 'full_msg' area?
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 is the full (and valid IPC message) and the handlers should cast it to the struct they use internally. The size of the message is in the message itself, in the header.
We could use struct sof_ipc_cmd_hdr *full_msg
, but it is not really the full message or we can say that it is a pointer to a header, but then it has to be documented that the header pointer is pointing to the beginning of the full message.
I prefer it to be void and let the handlers decide how to interpret the message they are given, in the 'core' we don't really care about any of the details.
@@ -345,6 +364,8 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) | |||
else | |||
sdev->boot_timeout = plat_data->desc->boot_timeout; | |||
|
|||
sof_set_fw_state(sdev, SOF_FW_BOOT_NOT_STARTED); |
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.
squash this change in previous 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.
The main reason for moving this is the introduction of the notification for clients which uses sdev->client_event_handler_mutex
and sdev->fw_state_handler_list
. We can not set the fw_state before those are initialized.
This is why this change is in this commit.
} | ||
|
||
kfree(full_msg); |
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 don't get why you are transposing the logic by doing ipc_msg_data() and then testing the callback.
Couldn't this done in an earlier patch if this is necessary so that this patch only adds the state notification?
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.
Before this patch I only allocated memory for the full_msg and retrieved the message from firmware if we had a handler for it. True, that it is unlikely, but it sounded the right thing to do. I could have done it with goto like this:
+ if (!rx_callback)
+ goto out;
+ /* read the full message as there we have rx handler for it */
+ full_msg = kmalloc(hdr.size, GFP_KERNEL);
+ if (!full_msg)
+ return;
+ err = snd_sof_ipc_msg_data(sdev, NULL, full_msg, hdr.size);
+ if (err < 0)
+ dev_err(sdev->dev, "failed to read message\n");
+ else
+ rx_callback(sdev, full_msg);
+ kfree(full_msg);
+ out:
ipc_log_header(sdev->dev, "ipc rx done", hdr.cmd);
if you prefer that.
Here we always need to allocate the full_msg as we don't know if there is a client waiting for the exact notification.
@@ -165,6 +165,9 @@ static int sof_resume(struct device *dev, bool runtime_resume) | |||
return ret; | |||
} | |||
|
|||
/* Notify clients about core resume */ | |||
sof_resume_clients(sdev); |
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 still don't get why this is necessary now that you provide a state information to the clients.
Or maybe you need to add a FW_SUSPEND/RESUME state and provide it clients which cannot do power management on their own.
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.
Right, I think clients should be able to use the entering to SOF_FW_BOOT_NOT_STARTED
as suspend and entering to SOF_FW_BOOT_COMPLETE
as resume.
I think we can drop the sof_suspend_client()
/ sof_resume_client()
and related infra. Most likely, I need to check to be sure.
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.
Right, I think clients should be able to use the entering to
SOF_FW_BOOT_NOT_STARTED
as suspend and entering toSOF_FW_BOOT_COMPLETE
as resume.I think we can drop the
sof_suspend_client()
/sof_resume_client()
and related infra. Most likely, I need to check to be sure.
@plbossart, I was too optimistic on this. Relying solely on the fw_state
change instead resume/suspend auxiliary bus callbacks does not work well.
There are several issues right know, I was able to fix only one:
[1] SOF_FW_BOOT_COMPLETE
state is set at a wrong point in time
It is set directly when the SOF_IPC_FW_READY
is received and it is OK, however the DSP is not yet ready. We need the snd_sof_dsp_post_fw_run()
to be run on HDA platforms.
I have fixed this with a new SOF_FW_BOOT_READY_OK
which is set in ipc.c, then after the snd_sof_dsp_post_fw_run()
we move to SOF_FW_BOOT_COMPLETE
.
[2] On suspend we change the fw_state to SOF_FW_BOOT_NOT_STARTED
after the DSP is powered off, clients can not clean and close things up at this point and causes lockups and DSP/HDA to crash completely
Moving the state change before the snd_sof_dsp_runtime_suspend()
/ snd_sof_dsp_suspend()
is kind of fixes it, but it is not a valid place to say the the DSP is off as it is not yet.
[3] With workaround for [1] and [2] there is a race which manifests on resume (runtime) that we are trying to send IPC message while we are still processing the SOF_IPC_FW_READY
- the ipc rx done: 0x70000000: FW_READY
is not printed before the dma-trace tries to re-enable the trace via the callback from state change.
Introducing another set of fw_states (SOF_FW_SUSPENDING/RESUMING) might give us a tool to work around some of the issues but the state handling around SOF must be revisited as SUSPENDING is essentially BOOT_COMPLETE during it's time, but RESUMING is a bit trickier. It is also a question on when to set the SUSPENDING state, most likely in the middle of the suspend function, which is not nice...
int ret; | ||
|
||
if (sof_client_get_fw_state(cdev) == SOF_FW_CRASHED) | ||
return -ENODEV; |
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 happened before this test was introduced? Did we get an error or a kernel oops?
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 first IPC tx would time-out (error prints from the core) and we aborted the test (error print in the flood test).
We could print in dmesg that the test can not be run due to the fact that the firmware is thought to be crashed.
There is definitely no point of trying to execute the test in this case.
I got requests for new features and I have kept patches as separate for easier review (new functionalities are like this), I can squash things down quite a bit, but new core features that we need to have for the SOF client infra to be operational are piling up. They could be split to separate PR (like the new fw_state). I also have tidy-up patches for the converted features, kept as separate to allow the conversion patch to be mostly a code move.
At the end what we want is to have a core and clients. The core would provide interface for the clients to implement support for features within the SOF firmware or to communicate with the firmware. In this sense the dma-trace should not be in the core and I think with the state notification we no longer have anything big against it.
What I fear is that if we have only plan for the easy ones we would end up rewriting things to support the complicated components. The dma-trace was a good exercise to bring out some of the things we never would have needed for the ipc-flood and the probes, they are different types of clients. |
Closing this as I have moved to #3136 due to the changes caused by squashing and new patch ordering. |
Hi,
this series is relatively big departure from previous versions (the latest was #2836 from me).
The high level concept is:
Dropped most of the reviewed-by, tested-by tags since not much is intact from the original versions, but I have kept @ranj063 as author where she was and @fredoh9 as co-author.
I have tested the IPC flood test with 3 instance and the probes on my TGL-H HDA device, all works correctly.
Reasons for a draft status:
Next steps: