-
Notifications
You must be signed in to change notification settings - Fork 140
New memory domain logic #5537
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: topic/sof-dev
Are you sure you want to change the base?
New memory domain logic #5537
Changes from all commits
3958e5d
0bf399f
f64beff
456d2cf
9d06525
83af640
eb13b52
9e793ed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -163,11 +163,15 @@ static const struct sof_topology_token comp_ext_tokens[] = { | |
| {SOF_TKN_COMP_SCHED_DOMAIN, SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_comp_domain, | ||
| offsetof(struct snd_sof_widget, comp_domain)}, | ||
| {SOF_TKN_COMP_DOMAIN_ID, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, | ||
| offsetof(struct snd_sof_widget, dp_domain_id)}, | ||
| {SOF_TKN_COMP_HEAP_BYTES_REQUIREMENT, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, | ||
| offsetof(struct snd_sof_widget, dp_heap_bytes)}, | ||
| offsetof(struct snd_sof_widget, domain_id)}, | ||
| {SOF_TKN_COMP_STACK_BYTES_REQUIREMENT, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, | ||
| offsetof(struct snd_sof_widget, dp_stack_bytes)}, | ||
| offsetof(struct snd_sof_widget, stack_bytes)}, | ||
| {SOF_TKN_COMP_INTERIM_HEAP_BYTES_REQUIREMENT, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, | ||
| offsetof(struct snd_sof_widget, interim_bytes)}, | ||
| {SOF_TKN_COMP_LIFETIME_HEAP_BYTES_REQUIREMENT, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, | ||
| offsetof(struct snd_sof_widget, lifetime_bytes)}, | ||
| {SOF_TKN_COMP_SHARED_BYTES_REQUIREMENT, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, | ||
| offsetof(struct snd_sof_widget, shared_bytes)}, | ||
| }; | ||
|
|
||
| static const struct sof_topology_token gain_tokens[] = { | ||
|
|
@@ -1332,6 +1336,26 @@ sof_ipc4_update_resource_usage(struct snd_sof_dev *sdev, struct snd_sof_widget * | |
| pipeline = pipe_widget->private; | ||
| pipeline->mem_usage += total; | ||
|
|
||
| /* | ||
| * If this is not a Data Processing module instance, add the | ||
| * required heap sizes to the sum of all modules instance's | ||
| * belonging to same pipeline and find the maximum stack | ||
| * requirement of all module instances belonging to the same | ||
| * pipeline. | ||
| */ | ||
| if (swidget->comp_domain != SOF_COMP_DOMAIN_DP) { | ||
| pipe_widget->interim_bytes += swidget->interim_bytes; | ||
| pipe_widget->lifetime_bytes += swidget->lifetime_bytes; | ||
| pipe_widget->shared_bytes += swidget->shared_bytes; | ||
| if (pipe_widget->stack_bytes < swidget->stack_bytes) | ||
| pipe_widget->stack_bytes = swidget->stack_bytes; | ||
|
|
||
| dev_dbg(sdev->dev, "%s mem reqs to %s lifetime %u heap %u shared %u stack %u", | ||
| swidget->widget->name, pipe_widget->widget->name, | ||
| pipe_widget->lifetime_bytes, pipe_widget->interim_bytes, | ||
| pipe_widget->shared_bytes, pipe_widget->stack_bytes); | ||
| } | ||
|
|
||
| /* Update base_config->cpc from the module manifest */ | ||
| sof_ipc4_update_cpc_from_manifest(sdev, fw_module, base_config); | ||
|
|
||
|
|
@@ -3040,55 +3064,70 @@ static int sof_ipc4_control_setup(struct snd_sof_dev *sdev, struct snd_sof_contr | |
| return 0; | ||
| } | ||
|
|
||
| static int sof_ipc4_widget_setup_msg_payload(struct snd_sof_dev *sdev, | ||
| struct snd_sof_widget *swidget, | ||
| struct sof_ipc4_msg *msg, | ||
| void *ipc_data, u32 ipc_size, | ||
| void **new_data) | ||
| static void sof_ipc4_add_init_ext_dp_memory_data(struct snd_sof_dev *sdev, | ||
| struct snd_sof_widget *swidget, | ||
| u32 *payload, u32 *ext_pos, | ||
| struct sof_ipc4_module_init_ext_object **hdr) | ||
| { | ||
| /* Add memory_data if comp_domain indicates DP */ | ||
| if (swidget->comp_domain == SOF_COMP_DOMAIN_DP) { | ||
| struct sof_ipc4_mod_init_ext_dp_memory_data *dp_mem_data; | ||
|
|
||
| *hdr = (struct sof_ipc4_module_init_ext_object *)&payload[*ext_pos]; | ||
| (*hdr)->header = | ||
| SOF_IPC4_MOD_INIT_EXT_OBJ_ID(SOF_IPC4_MOD_INIT_DATA_ID_DP_DATA) | | ||
| SOF_IPC4_MOD_INIT_EXT_OBJ_WORDS(DIV_ROUND_UP(sizeof(*dp_mem_data), | ||
| sizeof(u32))); | ||
| *ext_pos += DIV_ROUND_UP(sizeof(**hdr), sizeof(u32)); | ||
| dp_mem_data = (struct sof_ipc4_mod_init_ext_dp_memory_data *)&payload[*ext_pos]; | ||
| dp_mem_data->domain_id = swidget->domain_id; | ||
| dp_mem_data->stack_bytes = swidget->stack_bytes; | ||
| dp_mem_data->interim_heap_bytes = swidget->interim_bytes; | ||
| dp_mem_data->lifetime_heap_bytes = swidget->lifetime_bytes; | ||
| dp_mem_data->shared_bytes = swidget->shared_bytes; | ||
| *ext_pos += DIV_ROUND_UP(sizeof(*dp_mem_data), sizeof(u32)); | ||
| } | ||
| } | ||
|
|
||
| static int sof_ipc4_widget_mod_init_msg_payload(struct snd_sof_dev *sdev, | ||
| struct snd_sof_widget *swidget, | ||
| struct sof_ipc4_msg *msg, | ||
| void *ipc_data, u32 ipc_size, | ||
| void **new_data) | ||
| { | ||
| struct sof_ipc4_mod_init_ext_dp_memory_data *dp_mem_data; | ||
| struct sof_ipc4_module_init_ext_init *ext_init; | ||
| struct sof_ipc4_module_init_ext_object *hdr; | ||
| struct sof_ipc4_module_init_ext_object *hdr = NULL; | ||
| int new_size; | ||
| u32 *payload; | ||
| u32 ext_pos; | ||
|
|
||
| /* For the moment the only reason for adding init_ext_init payload is DP | ||
| * memory data. If both stack and heap size are 0 (= use default), then | ||
| * there is no need for init_ext_init payload. | ||
| */ | ||
| if (swidget->comp_domain != SOF_COMP_DOMAIN_DP) { | ||
| msg->extension &= ~SOF_IPC4_MOD_EXT_EXTENDED_INIT_MASK; | ||
| return 0; | ||
| } | ||
|
|
||
| payload = kzalloc(sdev->ipc->max_payload_size, GFP_KERNEL); | ||
| if (!payload) | ||
| return -ENOMEM; | ||
|
|
||
| /* Add ext_init first and set objects array flag to 1 */ | ||
| ext_init = (struct sof_ipc4_module_init_ext_init *)payload; | ||
| ext_init->word0 |= SOF_IPC4_MOD_INIT_EXT_OBJ_ARRAY_MASK; | ||
| ext_pos = DIV_ROUND_UP(sizeof(*ext_init), sizeof(u32)); | ||
|
|
||
| /* Add object array objects after ext_init */ | ||
|
|
||
| /* Add dp_memory_data if comp_domain indicates DP */ | ||
| if (swidget->comp_domain == SOF_COMP_DOMAIN_DP) { | ||
| hdr = (struct sof_ipc4_module_init_ext_object *)&payload[ext_pos]; | ||
| hdr->header = SOF_IPC4_MOD_INIT_EXT_OBJ_LAST_MASK | | ||
| SOF_IPC4_MOD_INIT_EXT_OBJ_ID(SOF_IPC4_MOD_INIT_DATA_ID_DP_DATA) | | ||
| SOF_IPC4_MOD_INIT_EXT_OBJ_WORDS(DIV_ROUND_UP(sizeof(*dp_mem_data), | ||
| sizeof(u32))); | ||
| ext_pos += DIV_ROUND_UP(sizeof(*hdr), sizeof(u32)); | ||
| dp_mem_data = (struct sof_ipc4_mod_init_ext_dp_memory_data *)&payload[ext_pos]; | ||
| dp_mem_data->domain_id = swidget->dp_domain_id; | ||
| dp_mem_data->stack_bytes = swidget->dp_stack_bytes; | ||
| dp_mem_data->heap_bytes = swidget->dp_heap_bytes; | ||
| ext_pos += DIV_ROUND_UP(sizeof(*dp_mem_data), sizeof(u32)); | ||
| } | ||
| sof_ipc4_add_init_ext_dp_memory_data(sdev, swidget, payload, &ext_pos, &hdr); | ||
|
|
||
| /* Add following object array items here */ | ||
|
|
||
| /* If another array object is added, remember clear previous OBJ_LAST bit */ | ||
| if (hdr) { | ||
| ext_init->word0 |= SOF_IPC4_MOD_INIT_EXT_OBJ_ARRAY_MASK; | ||
| hdr->header |= SOF_IPC4_MOD_INIT_EXT_OBJ_LAST_MASK; | ||
| } else { | ||
| /* | ||
| * NOTE: Remove this early bail out, when struct | ||
| * sof_ipc4_module_init_ext_init alone has some | ||
| * function. | ||
| */ | ||
| kfree(payload); | ||
| return 0; | ||
| } | ||
|
|
||
| /* Calculate final size and check that it fits to max payload size */ | ||
| new_size = ext_pos * sizeof(u32) + ipc_size; | ||
|
|
@@ -3111,6 +3150,76 @@ static int sof_ipc4_widget_setup_msg_payload(struct snd_sof_dev *sdev, | |
| return new_size; | ||
| } | ||
|
|
||
| static void sof_ipc4_widget_pipe_ext_obj_memory_data(struct snd_sof_dev *sdev, | ||
| struct snd_sof_widget *swidget, | ||
| u32 *payload, u32 *ext_pos, | ||
| struct sof_ipc4_glb_pipe_ext_object **hdr) | ||
| { | ||
| struct sof_ipc4_glb_pipe_ext_obj_memory_data *mem_data; | ||
|
|
||
| *hdr = (struct sof_ipc4_glb_pipe_ext_object *)&payload[*ext_pos]; | ||
| (*hdr)->header = | ||
| SOF_IPC4_GLB_PIPE_EXT_OBJ_ID(SOF_IPC4_GLB_PIPE_DATA_ID_MEM_DATA) | | ||
| SOF_IPC4_GLB_PIPE_EXT_OBJ_WORDS(DIV_ROUND_UP(sizeof(*mem_data), | ||
| sizeof(u32))); | ||
| *ext_pos += DIV_ROUND_UP(sizeof(**hdr), sizeof(u32)); | ||
| mem_data = (struct sof_ipc4_glb_pipe_ext_obj_memory_data *)&payload[*ext_pos]; | ||
| mem_data->domain_id = swidget->domain_id; | ||
| mem_data->stack_bytes = swidget->stack_bytes; | ||
| mem_data->interim_heap_bytes = swidget->interim_bytes; | ||
| mem_data->lifetime_heap_bytes = swidget->lifetime_bytes; | ||
| mem_data->shared_bytes = swidget->shared_bytes; | ||
| *ext_pos += DIV_ROUND_UP(sizeof(*mem_data), sizeof(u32)); | ||
|
|
||
| dev_dbg(sdev->dev, | ||
| "%s; domain_id %u stack %u interim %u lifetime %u shared %u bytes", | ||
| swidget->widget->name, mem_data->domain_id, mem_data->stack_bytes, | ||
| mem_data->interim_heap_bytes, mem_data->lifetime_heap_bytes, | ||
| mem_data->shared_bytes); | ||
| } | ||
|
|
||
| static int sof_ipc4_widget_pipe_create_msg_payload(struct snd_sof_dev *sdev, | ||
| struct snd_sof_widget *swidget, | ||
| struct sof_ipc4_msg *msg, | ||
| void **new_data) | ||
| { | ||
| struct sof_ipc4_glb_pipe_payload *payload_hdr; | ||
| struct sof_ipc4_glb_pipe_ext_object *hdr = NULL; | ||
| u32 *payload; | ||
| u32 ext_pos; | ||
|
|
||
| payload = kzalloc(sdev->ipc->max_payload_size, GFP_KERNEL); | ||
| if (!payload) | ||
| return -ENOMEM; | ||
|
|
||
| /* Add sof_ipc4_glb_pipe_payload and set array bit to 1 */ | ||
| payload_hdr = (struct sof_ipc4_glb_pipe_payload *)payload; | ||
| payload_hdr->word0 |= SOF_IPC4_GLB_PIPE_EXT_OBJ_ARRAY_MASK; | ||
| ext_pos = DIV_ROUND_UP(sizeof(*payload_hdr), sizeof(u32)); | ||
|
|
||
| sof_ipc4_widget_pipe_ext_obj_memory_data(sdev, swidget, payload, &ext_pos, &hdr); | ||
| /* Add following array objects here */ | ||
|
|
||
| if (!hdr) { | ||
| kfree(payload); | ||
| return 0; | ||
| } | ||
| /* Mark end of object array */ | ||
| hdr->header |= SOF_IPC4_GLB_PIPE_EXT_OBJ_LAST_MASK; | ||
|
|
||
| /* Put total payload size in words to the payload header */ | ||
| payload_hdr->word0 |= SOF_IPC4_GLB_PIPE_PAYLOAD_WORDS(ext_pos); | ||
| *new_data = payload; | ||
|
|
||
| /* Update msg extension bits according to the payload changes */ | ||
| msg->extension |= SOF_IPC4_GLB_PIPE_PAYLOAD_MASK; | ||
|
|
||
| dev_dbg(sdev->dev, "%s: payload word0 %#x", swidget->widget->name, | ||
| payload_hdr->word0); | ||
|
|
||
| return ext_pos * sizeof(int32_t); | ||
| } | ||
|
|
||
| static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) | ||
| { | ||
| struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; | ||
|
|
@@ -3264,8 +3373,8 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget | |
| swidget->widget->name, swidget->pipeline_id, module_id, | ||
| swidget->instance_id, swidget->core); | ||
|
|
||
| ret = sof_ipc4_widget_setup_msg_payload(sdev, swidget, msg, ipc_data, ipc_size, | ||
| &ext_data); | ||
| ret = sof_ipc4_widget_mod_init_msg_payload(sdev, swidget, msg, ipc_data, ipc_size, | ||
| &ext_data); | ||
| if (ret < 0) | ||
| goto fail; | ||
|
|
||
|
|
@@ -3277,6 +3386,17 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget | |
| dev_dbg(sdev->dev, "Create pipeline %s (pipe %d) - instance %d, core %d\n", | ||
| swidget->widget->name, swidget->pipeline_id, | ||
| swidget->instance_id, swidget->core); | ||
|
|
||
| msg->extension &= ~SOF_IPC4_GLB_PIPE_PAYLOAD_MASK; | ||
| ret = sof_ipc4_widget_pipe_create_msg_payload(sdev, swidget, msg, | ||
| &ext_data); | ||
| if (ret < 0) | ||
| goto fail; | ||
|
|
||
| if (ret > 0) { | ||
| ipc_size = ret; | ||
| ipc_data = ext_data; | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you take a look at this patch in the compressed support series? Would it be possible to align with that implementation, I think it would be much easier to extend (adding the compr on top of this), that is.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ack - reuse would be best.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ujfalusi Where can I find this commit (fetching your github or sof-linux did not work)? Easiest would be if I could rebase my branch on top of the compressed support code. Is it close to merging stage? Could it be spit so so that the mod init payload code would be merged early, before the rest?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, I am not any more sure what I should reuse, or to what exactly to align with. I could of course, just within this PR, write a common function to add either struct sof_ipc4_glb_pipe_ext_obj_memory_data or struct sof_ipc4_mod_init_ext_dp_memory_data to a payload object array. The structs are actually identical, but by definition they are different structs an parts of different payloads, even if the object array concept is the same in the both payloads. That is not what you are asking, is it? But if I could get the processing module configuration commit early and rebase this PR on top of that, then that should solve the merging problem with compress PR, shouldn't it?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that what I meant, to follow the pattern so it is going to be easier to move forward with other changes (with the way you do it is going to be a bit of a pain to rework the compr stuff, not that it is hard, just trying to cut corners) |
||
| } | ||
|
|
||
| msg->data_size = ipc_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.
nitpick: I'd do
if (!hdr) {kfree(payload); return 0;}and then continue below with the restThere 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 wanted to have the both sides of the if statement, because it may be that sof_ipc4_add_init_ext_dp_memory_data() did not add an object to the object array, and then we should not add the array at all, let alone mark the last element. There was an ext init payload even before my time and there are some bits defined there, so we may need to add the payload even if the array is not present. In that situation if (hdr) part remains, but the else branch should be removed. If I am to do something about this, then that would be adding the non array part always, e.g removing the the else branch.