Skip to content

Conversation

@jsarha
Copy link
Contributor

@jsarha jsarha commented Sep 26, 2025

Code to decode pipline create messages payload. E.g. this code is written to test this PR: thesofproject/linux#5537

Copy link
Member

@lgirdwood lgirdwood left a 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.

@jsarha jsarha force-pushed the pipeline_memory_attributes branch from ac3bf18 to 5c3c095 Compare September 30, 2025 20:59
@lyakh lyakh changed the title Code to decode pipline create messages payload Code to decode pipeline create messages payload Oct 2, 2025
@jsarha jsarha force-pushed the pipeline_memory_attributes branch from e43cb7b to 9f5d981 Compare October 7, 2025 21:37
@jsarha jsarha force-pushed the pipeline_memory_attributes branch 2 times, most recently from 2dc8ac4 to 7e4bb9a Compare November 11, 2025 18:06

/* Check if there is space for the object header */
if ((char *)(obj + 1) - data > size) {
tr_err(&ipc_tr, "obj header overflow, %u > %u",
Copy link
Collaborator

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?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved by mistake?

Copy link
Contributor Author

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.

@jsarha jsarha force-pushed the pipeline_memory_attributes branch from 7e4bb9a to d9de565 Compare December 3, 2025 19:17
@jsarha
Copy link
Contributor Author

jsarha commented Dec 3, 2025

@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.

@jsarha jsarha force-pushed the pipeline_memory_attributes branch from d9de565 to 4d8a457 Compare December 14, 2025 23:14
@jsarha
Copy link
Contributor Author

jsarha commented Dec 14, 2025

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.

@jsarha
Copy link
Contributor Author

jsarha commented Dec 16, 2025

Finaly the module init payload decoding is happening where it should be. Ready for review.

@jsarha jsarha marked this pull request as ready for review December 16, 2025 16:02
Copilot AI review requested due to automatic review settings December 16, 2025 16:02
@jsarha
Copy link
Contributor Author

jsarha commented Dec 16, 2025

@lgirdwood should I rebase this or is it better to keep it on top of older base still?

@lgirdwood
Copy link
Member

@lgirdwood should I rebase this or is it better to keep it on top of older base still?

Best to rebase and adding @ranj063

Copy link

Copilot AI left a 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_requirement to separate interim_heap_bytes_requirement, lifetime_heap_bytes_requirement, and shared_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_data structure instead of storing values directly in module_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.

@jsarha jsarha force-pushed the pipeline_memory_attributes branch 2 times, most recently from 7dd6358 to 7727c82 Compare December 16, 2025 21:52
@jsarha
Copy link
Contributor Author

jsarha commented Dec 16, 2025

Fixed copilot spotted typos.

…code()

Use %zu in size_t prints in module_ext_init_decode().

Signed-off-by: Jyri Sarha <[email protected]>
@jsarha
Copy link
Contributor Author

jsarha commented Dec 16, 2025

... and rebased.


/* Check if there is space for the object header */
if ((char *)(obj + 1) - data > size) {
tr_err(&ipc_tr, "obj header overflow, %u > %u",
Copy link
Collaborator

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;
Copy link
Collaborator

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?

Copy link
Collaborator

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.

Copy link
Contributor Author

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)) {
Copy link
Collaborator

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

Copy link
Contributor Author

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);
Copy link
Collaborator

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 :-)

Copy link
Member

@lgirdwood lgirdwood left a 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
Copy link
Member

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.
Copy link
Member

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.

Copy link
Collaborator

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.

Copy link
Member

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
Copy link
Member

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.

Comment on lines 138 to 144
struct pipeline_params {
uint32_t domain_id;
size_t stack_bytes;
size_t lifetime_bytes;
size_t interim_bytes;
size_t shared_bytes;
};
Copy link
Member

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
Copy link
Member

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 ?

Copy link
Contributor Author

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.

Copy link
Collaborator

@kv2019i kv2019i left a 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.
Copy link
Collaborator

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.

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);
Copy link
Collaborator

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kv2019i & @lyakh since apparently the library builds do not require cache invalidation (I assume library builds have been tested), shouldn't this whole cache invalidation code be behind #ifndef CONFIG_LIBRARY ? (I can still use data ptr instead of MAILBOX_HOSTBOX_BASE).

return NULL;
comp_warn(dev, "dp_data object too small %zu < %zu",
obj->object_words * sizeof(uint32_t), sizeof(*dp_data));
break;
Copy link
Collaborator

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.

Copy link
Collaborator

@kv2019i kv2019i left a 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
Copy link
Contributor Author

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"


/* Check if there is space for the object header */
if ((char *)(obj + 1) - data > size) {
tr_err(&ipc_tr, "obj header overflow, %u > %u",
Copy link
Contributor Author

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.

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);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kv2019i & @lyakh since apparently the library builds do not require cache invalidation (I assume library builds have been tested), shouldn't this whole cache invalidation code be behind #ifndef CONFIG_LIBRARY ? (I can still use data ptr instead of MAILBOX_HOSTBOX_BASE).

token_ref "comp.word"
}

# These default values are here until we have measured module specific numbers
Copy link
Contributor Author

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)) {
Copy link
Contributor Author

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;
Copy link
Contributor Author

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.

@lyakh
Copy link
Collaborator

lyakh commented Dec 17, 2025

I am bit surprised that that castiing a const pointer to non const integer pointer does not cause a warning

@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.

Jyri Sarha added 2 commits December 17, 2025 18:24
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]>
@jsarha jsarha force-pushed the pipeline_memory_attributes branch 2 times, most recently from cb378d1 to 2ef7ab4 Compare December 18, 2025 10:16
Jyri Sarha added 6 commits December 18, 2025 21:51
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]>
@jsarha jsarha force-pushed the pipeline_memory_attributes branch from 2ef7ab4 to e09a0b1 Compare December 18, 2025 20:00
@jsarha
Copy link
Contributor Author

jsarha commented Dec 18, 2025

Tobe squashed commits squashed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants