-
Notifications
You must be signed in to change notification settings - Fork 350
Memory attributes to user space dp module #10603
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?
Changes from all commits
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 |
|---|---|---|
|
|
@@ -58,22 +58,55 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv, | |
| #endif | ||
|
|
||
| static struct dp_heap_user *module_adapter_dp_heap_new(const struct comp_ipc_config *config, | ||
| const struct module_ext_init_data *ext_init, | ||
| size_t *heap_size) | ||
| { | ||
| const size_t heap_prefix_size = ALIGN_UP(sizeof(struct dp_heap_user), 4); | ||
| /* src-lite with 8 channels has been seen allocating 14k in one go */ | ||
| /* FIXME: the size will be derived from configuration */ | ||
| const size_t buf_size = 20 * 1024; | ||
| size_t buf_size = CONFIG_SOF_USERSPACE_DP_DEFAULT_HEAP_SIZE; | ||
|
|
||
| #if CONFIG_IPC_MAJOR_4 | ||
| if (config->ipc_extended_init && ext_init && ext_init->dp_data && | ||
| (ext_init->dp_data->lifetime_heap_bytes > 0 || | ||
| ext_init->dp_data->interim_heap_bytes > 0)) { | ||
| if (ext_init->dp_data->lifetime_heap_bytes > 64*1024*1024 || | ||
| ext_init->dp_data->interim_heap_bytes > 64*1024*1024) { | ||
| LOG_ERR("Insanely large lifetime %u or interim %u heap size for %#x", | ||
| ext_init->dp_data->lifetime_heap_bytes, | ||
| ext_init->dp_data->interim_heap_bytes, config->id); | ||
| return NULL; | ||
| } | ||
|
|
||
| /* | ||
| * For the moment there is only one heap so sum up | ||
| * lifetime and interim values. It is also a conscious | ||
| * decision here to count the size of struct | ||
| * dp_heap_user to be included into required heap | ||
| * size. | ||
| */ | ||
| buf_size = ext_init->dp_data->lifetime_heap_bytes + | ||
| ext_init->dp_data->interim_heap_bytes; | ||
| LOG_DBG("%u + %u = %zu byte heap size requested in IPC for %#x", | ||
| ext_init->dp_data->lifetime_heap_bytes, | ||
| ext_init->dp_data->interim_heap_bytes, buf_size, config->id); | ||
| } | ||
|
Comment on lines
+87
to
+92
|
||
| #endif | ||
| if (buf_size < heap_prefix_size) { | ||
| LOG_ERR("Too small heap size %zu (< %zu) for %#x", buf_size, heap_prefix_size, | ||
| config->id); | ||
| return NULL; | ||
| } | ||
|
|
||
| LOG_INF("Allocating %zu byte heap (default %zu) for %#x", buf_size, | ||
| CONFIG_SOF_USERSPACE_DP_DEFAULT_HEAP_SIZE, config->id); | ||
| /* Keep uncached to match the default SOF heap! */ | ||
| uint8_t *mod_heap_mem = rballoc_align(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, | ||
| buf_size, PAGE_SZ); | ||
| uint8_t *mod_heap_mem = rballoc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, buf_size); | ||
|
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. |
||
|
|
||
| if (!mod_heap_mem) | ||
| return NULL; | ||
|
|
||
| struct dp_heap_user *mod_heap_user = (struct dp_heap_user *)mod_heap_mem; | ||
| struct k_heap *mod_heap = &mod_heap_user->heap; | ||
| const size_t heap_prefix_size = ALIGN_UP(sizeof(*mod_heap_user), 4); | ||
| void *mod_heap_buf = mod_heap_mem + heap_prefix_size; | ||
|
|
||
| *heap_size = buf_size - heap_prefix_size; | ||
|
|
@@ -86,8 +119,10 @@ static struct dp_heap_user *module_adapter_dp_heap_new(const struct comp_ipc_con | |
| return mod_heap_user; | ||
| } | ||
|
|
||
| static struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv, | ||
| const struct comp_ipc_config *config) | ||
| static | ||
| struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv, | ||
| const struct comp_ipc_config *config, | ||
| const struct module_ext_init_data *ext_init) | ||
| { | ||
| struct k_heap *mod_heap; | ||
| /* | ||
|
|
@@ -104,7 +139,7 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv | |
|
|
||
| if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP && IS_ENABLED(CONFIG_USERSPACE) && | ||
| !IS_ENABLED(CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP)) { | ||
| mod_heap_user = module_adapter_dp_heap_new(config, &heap_size); | ||
| mod_heap_user = module_adapter_dp_heap_new(config, ext_init, &heap_size); | ||
| if (!mod_heap_user) { | ||
| comp_cl_err(drv, "Failed to allocate DP module heap"); | ||
| return NULL; | ||
|
|
@@ -220,8 +255,14 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv, | |
| return NULL; | ||
| } | ||
| #endif | ||
| const struct module_ext_init_data *ext_init = | ||
|
Contributor
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. Minor: You could probably pass only dp_data to module_adapter_mem_alloc instead of the entire structure ext_data.
Contributor
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. dp_data is defined only in ipc4 headers, so I think its easiest to keep it behind #if , and keep the module_adapter_mem_alloc() arguments the way they are. |
||
| #if CONFIG_IPC_MAJOR_4 | ||
| &ext_data; | ||
| #else | ||
| NULL; | ||
| #endif | ||
|
|
||
| struct processing_module *mod = module_adapter_mem_alloc(drv, config); | ||
| struct processing_module *mod = module_adapter_mem_alloc(drv, config, ext_init); | ||
|
|
||
| if (!mod) | ||
| return NULL; | ||
|
|
@@ -234,6 +275,18 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv, | |
|
|
||
| struct comp_dev *dev = mod->dev; | ||
|
|
||
| dst = &mod->priv.cfg; | ||
| /* | ||
| * NOTE: dst->ext_data points to stack variable and contains | ||
| * pointers to IPC payload mailbox, so its only valid in | ||
| * functions that are called from this function. This is | ||
| * why the pointer is set to NULL before this function | ||
| * exits. | ||
| */ | ||
| #if CONFIG_IPC_MAJOR_4 | ||
| dst->ext_data = &ext_data; | ||
| #endif | ||
|
|
||
| #if CONFIG_ZEPHYR_DP_SCHEDULER | ||
| /* create a task for DP processing */ | ||
| if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP) { | ||
|
|
@@ -246,16 +299,6 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv, | |
| } | ||
| #endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ | ||
|
|
||
| dst = &mod->priv.cfg; | ||
| /* | ||
| * NOTE: dst->ext_data points to stack variable and contains | ||
| * pointers to IPC payload mailbox, so its only valid in | ||
| * functions that called from this function. This why | ||
| * the pointer is set NULL before this function exits. | ||
| */ | ||
| #if CONFIG_IPC_MAJOR_4 | ||
| dst->ext_data = &ext_data; | ||
| #endif | ||
| ret = module_adapter_init_data(dev, dst, config, &spec); | ||
| if (ret) { | ||
| comp_err(dev, "%d: module init data failed", | ||
|
|
||
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.
DP heap size calculation appears to under-allocate and can underflow.
buf_sizeis set tolifetime_heap_bytes + interim_heap_bytes, but later the usable heap is computed asbuf_size - heap_prefix_size; if the IPC values are meant to be the required heap size (per IPC4 comments), you likely need to allocaterequired + heap_prefix_sizeso the heap has the requested capacity. Also, if the sum is smaller thanheap_prefix_size,buf_size - heap_prefix_sizewill wrap (size_t underflow) andk_heap_init()will be called with an invalid huge size.