-
Notifications
You must be signed in to change notification settings - Fork 349
Code to decode pipeline create messages payload #10265
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
base: main
Are you sure you want to change the base?
Conversation
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.
LGTM, we can followup with the allocations per pipeline or domain later.
ac3bf18 to
5c3c095
Compare
e43cb7b to
9f5d981
Compare
2dc8ac4 to
7e4bb9a
Compare
src/ipc/ipc4/helper.c
Outdated
|
|
||
| /* Check if there is space for the object header */ | ||
| if ((char *)(obj + 1) - data > size) { | ||
| tr_err(&ipc_tr, "obj header overflow, %u > %u", |
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.
shouldn't the format be %zu for size here and below?
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.
resolved by mistake?
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.
Argh... I fixed this in one place already, but the copy-pasted version is still in the original form.
7e4bb9a to
d9de565
Compare
|
@lgirdwood this is now updated so that it should be almost exact match to #10281 , vpages code only needs to use the params passed to pipeline_new(). But to use this the topology should be built from this PR and you need my linux driver PR #10281 too to pass down the topology info. |
d9de565 to
4d8a457
Compare
|
This version address the changes requested to thesofproject/linux#5537 . I still need to move the module init payload decoding to happen already before module_adapter_mem_alloc() -call, before this is ready. |
|
Finaly the module init payload decoding is happening where it should be. Ready for review. |
|
@lgirdwood should I rebase this or is it better to keep it on top of older base still? |
Best to rebase and adding @ranj063 |
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.
Pull request overview
This PR implements decoding logic for pipeline creation message payloads in IPC4, enabling the parsing of extended pipeline initialization data such as memory requirements (stack, heap, shared memory). The changes support testing against a corresponding Linux kernel PR that extends pipeline creation capabilities.
Key Changes:
- Updated memory requirement tokens in topology configuration from a single
heap_bytes_requirementto separateinterim_heap_bytes_requirement,lifetime_heap_bytes_requirement, andshared_bytes_requirement - Added
ipc4_create_pipeline_payload_decode()function to parse extended pipeline creation payloads - Refactored module initialization to pass extended data through a new
module_ext_init_datastructure instead of storing values directly inmodule_config
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/topology/topology2/include/components/widget-common.conf | Updates topology token definitions for new memory requirement types and adds default values |
| tools/topology/topology2/include/common/tokens.conf | Adds token IDs for the new memory requirement types |
| test/cmocka/src/audio/pipeline/pipeline_new.c | Updates test to pass NULL for new pipeline parameters argument |
| src/ipc/ipc4/helper.c | Implements payload decoding logic and updates pipeline creation to accept extended parameters |
| src/ipc/ipc3/helper.c | Updates pipeline creation call to pass NULL for new parameters argument |
| src/include/sof/audio/pipeline.h | Adds pipeline_params structure and updates pipeline_new() signature |
| src/include/sof/audio/module_adapter/module/generic.h | Declares module_ext_init_decode() function with IPC4-specific implementation |
| src/include/module/module/base.h | Adds module_ext_init_data structure and refactors module_config to use it |
| src/include/ipc4/pipeline.h | Defines structures for pipeline extended payload objects |
| src/include/ipc4/module.h | Updates module initialization structure to include separate heap memory fields |
| src/audio/pipeline/pipeline-graph.c | Updates pipeline_new() signature to accept pipeline parameters |
| src/audio/module_adapter/module_adapter_ipc4.c | Refactors module extension decoding to populate module_ext_init_data instead of module_config |
| src/audio/module_adapter/module_adapter.c | Updates module adapter initialization to decode extended data and manage its lifecycle |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
7dd6358 to
7727c82
Compare
|
Fixed copilot spotted typos. |
…code() Use %zu in size_t prints in module_ext_init_decode(). Signed-off-by: Jyri Sarha <[email protected]>
|
... and rebased. |
src/ipc/ipc4/helper.c
Outdated
|
|
||
| /* Check if there is space for the object header */ | ||
| if ((char *)(obj + 1) - data > size) { | ||
| tr_err(&ipc_tr, "obj header overflow, %u > %u", |
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.
resolved by mistake?
| return NULL; | ||
| comp_warn(dev, "dp_data object too small %zu < %zu", | ||
| obj->object_words * sizeof(uint32_t), sizeof(*dp_data)); | ||
| 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.
why is this not fatal any more? Also break only takes you out of switch, not out of the loop, is that correct?
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 a bit suspicious, this goes on to access "dp_data->interim_heap_bytes" from the too small object. This does not look correct.
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.
This is mandatory if we go and redefine "struct ipc4_module_init_ext_obj_dp_data". Otherwise payloads sent by an older linux version would always fail dp module creation.
But fear not, non of the data in the too short data object is used. Its all ignored as all of that code accessing the data is within the case block. And we need to continue the decoding loop in case there is some other objects there that we can decode correctly.
| const struct ipc4_module_init_ext_obj_dp_data *dp_data = | ||
| (const struct ipc4_module_init_ext_obj_dp_data *)(obj + 1); | ||
|
|
||
| if (obj->object_words * sizeof(uint32_t) < sizeof(*dp_data)) { |
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.
to the commit message, I understand by "released" you mean it's already a part of the ABI? Maybe better use that wording, since I first thought "released" meant "freed" which was confusing. (unrelated to this commit) just noticing, that module_ext_init_decode() returns a pointer of type struct ipc4_base_module_extended_cfg which should only be appropriate for the base module? Strange
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.
Will fix the commit message.
The reason is that the base config follows ext_init in the payload, and if there is anything left aftere ext_init, it should be base config. Anyway, this is going way when I move module_ext_init_decode()-call to module_adapter_new_ext().
| * words from stack, | ||
| */ | ||
| struct ipc_config_process spec = | ||
| *((struct ipc_config_process *) const_spec); |
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.
please use const for type-casting just for the peace of mind of imperfect humans like me :-)
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.
A few opens on my end but looking like its almost ready.
| } | ||
|
|
||
| ## Lifetime heap memory allocation requirement in bytes for this component. | ||
| ## This token's value indicates the amount of allocated memory needed at component init phase |
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 used over the lifetime of the component until the component is destroyed.
|
|
||
| ## Heap size requirement in bytes for this component. Zero indicates default heap size. | ||
| DefineAttribute."heap_bytes_requirement" { | ||
| ## Interim Heap size requirement in bytes for this component. |
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.
used for resources that may change in size or be freed during the lifetime of the component.
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.
This is still a bit hard to understand. Maybe add an example for each type (does not have be real, just a practical example of what an algorithm module could use this heap type for). I think that will make this easier follow.
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.
you could state kcontrols, fast get/put(), as examples.
| } | ||
|
|
||
| ## Shared memory allocation requirement in bytes for this component. | ||
| ## this token's value indicates the amount of shared memory the component may need to allocated |
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.
that may be shared to other components.
src/include/sof/audio/pipeline.h
Outdated
| struct pipeline_params { | ||
| uint32_t domain_id; | ||
| size_t stack_bytes; | ||
| size_t lifetime_bytes; | ||
| size_t interim_bytes; | ||
| size_t shared_bytes; | ||
| }; |
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 add more doxygen comments here for this struct and members
| token_ref "comp.word" | ||
| } | ||
|
|
||
| # These default values are here until we have measured module specific numbers |
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.
Will these be in the base class and be default until overridden by each module ?
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. This was fastest way to get everything working. I think we should eventually remove them when we have component specific default values in place.
kv2019i
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.
Observations inline
|
|
||
| ## Heap size requirement in bytes for this component. Zero indicates default heap size. | ||
| DefineAttribute."heap_bytes_requirement" { | ||
| ## Interim Heap size requirement in bytes for this component. |
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.
This is still a bit hard to understand. Maybe add an example for each type (does not have be real, just a practical example of what an algorithm module could use this heap type for). I think that will make this easier follow.
src/ipc/ipc4/helper.c
Outdated
| dcache_invalidate_region((__sparse_force void __sparse_cache *)MAILBOX_HOSTBOX_BASE, | ||
| MAILBOX_HOSTBOX_SIZE); | ||
| sys_cache_data_invd_range((__sparse_force void __sparse_cache *)MAILBOX_HOSTBOX_BASE, | ||
| ipc_config.ipc_config_size); |
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.
These are good additions. This is overlapping a bit with my IPC payload access rework #10346 but that's stuck now due to dependencies, so no problem with you modifying these 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.
| return NULL; | ||
| comp_warn(dev, "dp_data object too small %zu < %zu", | ||
| obj->object_words * sizeof(uint32_t), sizeof(*dp_data)); | ||
| 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.
Looks a bit suspicious, this goes on to access "dp_data->interim_heap_bytes" from the too small object. This does not look correct.
kv2019i
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.
Observations inline
| num_input_audio_formats 415 | ||
| num_output_audio_formats 416 | ||
| no_wname_in_kcontrol_name 417 | ||
| scheduler_domain 418 |
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.
commit message: Proof reader "fixed" my typoed "shared" to "shaded"
src/ipc/ipc4/helper.c
Outdated
|
|
||
| /* Check if there is space for the object header */ | ||
| if ((char *)(obj + 1) - data > size) { | ||
| tr_err(&ipc_tr, "obj header overflow, %u > %u", |
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.
Argh... I fixed this in one place already, but the copy-pasted version is still in the original form.
src/ipc/ipc4/helper.c
Outdated
| dcache_invalidate_region((__sparse_force void __sparse_cache *)MAILBOX_HOSTBOX_BASE, | ||
| MAILBOX_HOSTBOX_SIZE); | ||
| sys_cache_data_invd_range((__sparse_force void __sparse_cache *)MAILBOX_HOSTBOX_BASE, | ||
| ipc_config.ipc_config_size); |
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.
| token_ref "comp.word" | ||
| } | ||
|
|
||
| # These default values are here until we have measured module specific numbers |
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. This was fastest way to get everything working. I think we should eventually remove them when we have component specific default values in place.
| const struct ipc4_module_init_ext_obj_dp_data *dp_data = | ||
| (const struct ipc4_module_init_ext_obj_dp_data *)(obj + 1); | ||
|
|
||
| if (obj->object_words * sizeof(uint32_t) < sizeof(*dp_data)) { |
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.
Will fix the commit message.
The reason is that the base config follows ext_init in the payload, and if there is anything left aftere ext_init, it should be base config. Anyway, this is going way when I move module_ext_init_decode()-call to module_adapter_new_ext().
| return NULL; | ||
| comp_warn(dev, "dp_data object too small %zu < %zu", | ||
| obj->object_words * sizeof(uint32_t), sizeof(*dp_data)); | ||
| 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.
This is mandatory if we go and redefine "struct ipc4_module_init_ext_obj_dp_data". Otherwise payloads sent by an older linux version would always fail dp module creation.
But fear not, non of the data in the too short data object is used. Its all ignored as all of that code accessing the data is within the case block. And we need to continue the decoding loop in case there is some other objects there that we can decode correctly.
@jsarha I think that's exactly how it's designed - the compiler respects the explicit cast and relies on the coder knowing what they're doing. Without a cast it would warn. Then there's a bunch of compiler flags to modify that "naive default" of which I certainly don't know all. |
Add lifetime_bytes_requirement and shared_bytes_requirement widget attributes. This token's value indicates the amount of heap memory needed at component initialization phase. Signed-off-by: Jyri Sarha <[email protected]>
Adds structs and definitions for adding a payload to struct ipc4_pipeline_create message. The structure of the payload is very similar to struct ipc4_module_init_ext_init payload for struct ipc4_module_init_instance. Signed-off-by: Jyri Sarha <[email protected]>
cb378d1 to
2ef7ab4
Compare
Add ipc4_create_pipeline_payload_decode() and call it if struct ipc4_pipeline_create's extension.r.payload bit is set. The function decodes the message payload, logs the contents, but does not store the information anywhere. Signed-off-by: Jyri Sarha <[email protected]>
Invalidate cache for only the module init payload size not the whole mailbox. Signed-off-by: Jyri Sarha <[email protected]>
Pass create pipeline payload parameters down to pipeline_new() by using struct pipeline_params. That is the place where the data will be used. Signed-off-by: Jyri Sarha <[email protected]>
…mory Add default values for stack, lifetime heap, interim heap, and shared memory sizes for all widgets, e.g. module instances. These values were tested with vpages branch and all cases that I tried worked with them. Eventually each module should be added with more accurate values, based on measurements. Signed-off-by: Jyri Sarha <[email protected]>
…data Update struct ipc4_module_init_ext_obj_dp_data to match what is required for latest user space features. This is a tricky change as it chenges already part of ABI. However, as the structure was not really used for anything before, changing it should be safe. That is with one exception. The case where an earlier SOF driver sends us the old smaller struct identifier with IPC4_MOD_INIT_DATA_ID_DP_DATA, then we should not fail on that, but only ignore the struct. This is why "return" is changed to "break" in case IPC4_MOD_INIT_DATA_ID_DP_DATA. Signed-off-by: Jyri Sarha <[email protected]>
Move module_ext_init_decode()-call earlier in call chain so that struct ipc4_module_init_ext_obj_dp_data is available when module_adapter_mem_alloc() is called. That is, if the struct ipc4_module_init_ext_object is present in the struct ipc4_module_init_ext_init payload. To accomplish this I needed to redesign how module_ext_init_decode() works and how its called a bit. Signed-off-by: Jyri Sarha <[email protected]>
2ef7ab4 to
e09a0b1
Compare
|
Tobe squashed commits squashed. |
Code to decode pipline create messages payload. E.g. this code is written to test this PR: thesofproject/linux#5537