-
Notifications
You must be signed in to change notification settings - Fork 349
part 2 of #10287 #10302
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?
part 2 of #10287 #10302
Changes from all commits
63ee731
99198c5
736fe2b
61cb923
1bb643d
3740f84
8b2881c
6963604
b6c6388
7751211
cf70560
89189d0
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 |
|---|---|---|
|
|
@@ -23,6 +23,7 @@ | |
| #include <sof/platform.h> | ||
| #include <sof/ut.h> | ||
| #include <rtos/interrupt.h> | ||
| #include <rtos/kernel.h> | ||
| #include <rtos/symbol.h> | ||
| #include <limits.h> | ||
| #include <stdint.h> | ||
|
|
@@ -44,6 +45,148 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv, | |
| return module_adapter_new_ext(drv, config, spec, NULL); | ||
| } | ||
|
|
||
| #if CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP | ||
| static struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv, | ||
| const struct comp_ipc_config *config) | ||
| { | ||
| struct comp_dev *dev = comp_alloc(drv, sizeof(*dev)); | ||
|
|
||
| if (!dev) { | ||
| comp_cl_err(drv, "failed to allocate memory for comp_dev"); | ||
| return NULL; | ||
| } | ||
|
|
||
| /* allocate module information. | ||
| * for DP shared modules this struct must be accessible from all cores | ||
| * Unfortunately at this point there's no information of components the module | ||
| * will be bound to. So we need to allocate shared memory for each DP module | ||
| * To be removed when pipeline 2.0 is ready | ||
| */ | ||
| int flags = config->proc_domain == COMP_PROCESSING_DOMAIN_DP ? | ||
| SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER; | ||
|
|
||
| struct processing_module *mod = module_driver_heap_rzalloc(drv->user_heap, flags, | ||
| sizeof(*mod)); | ||
|
|
||
| if (!mod) { | ||
| comp_err(dev, "failed to allocate memory for module"); | ||
| goto err; | ||
| } | ||
|
|
||
| mod->dev = dev; | ||
|
|
||
| return mod; | ||
|
|
||
| err: | ||
| module_driver_heap_free(drv->user_heap, dev); | ||
|
|
||
| return NULL; | ||
| } | ||
|
|
||
| static void module_adapter_mem_free(struct processing_module *mod) | ||
| { | ||
| const struct comp_driver *drv = mod->dev->drv; | ||
|
|
||
| #if CONFIG_IPC_MAJOR_4 | ||
| module_driver_heap_free(drv->user_heap, mod->priv.cfg.input_pins); | ||
| #endif | ||
| module_driver_heap_free(drv->user_heap, mod->dev); | ||
| module_driver_heap_free(drv->user_heap, mod); | ||
| } | ||
| #else | ||
|
|
||
| #if CONFIG_MM_DRV | ||
| #define PAGE_SZ CONFIG_MM_DRV_PAGE_SIZE | ||
| #else | ||
| #include <platform/platform.h> | ||
| #define PAGE_SZ HOST_PAGE_SIZE | ||
| #endif | ||
|
|
||
| static struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv, | ||
| const struct comp_ipc_config *config) | ||
| { | ||
| uint8_t *mod_heap_mem; | ||
| struct k_heap *mod_heap; | ||
| int flags; | ||
|
|
||
| if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP) { | ||
| /* src-lite with 8 channels has been seen allocating 14k in one go */ | ||
| /* FIXME: the size will be derived from configuration */ | ||
| const size_t heap_size = 20 * 1024; | ||
|
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. Apparently this value is meant to be passed via IPC and come from topology. Until that’s implemented, it would make more sense to move it to configuration rather than hardcoding it. |
||
|
|
||
| /* Keep uncached to match the default SOF heap! */ | ||
| mod_heap_mem = rballoc_align(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, | ||
|
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. "wow... heap on heap... I guess, why not" :) |
||
| heap_size, PAGE_SZ); | ||
| if (!mod_heap_mem) | ||
| return NULL; | ||
|
|
||
| const size_t heap_prefix_size = ALIGN_UP(sizeof(*mod_heap), 8); | ||
| void *mod_heap_buf = mod_heap_mem + heap_prefix_size; | ||
|
|
||
| mod_heap = (struct k_heap *)mod_heap_mem; | ||
| k_heap_init(mod_heap, mod_heap_buf, heap_size - heap_prefix_size); | ||
|
|
||
| flags = SOF_MEM_FLAG_COHERENT; | ||
| } else { | ||
| mod_heap_mem = NULL; | ||
| mod_heap = NULL; | ||
|
|
||
| flags = 0; | ||
| } | ||
|
|
||
| struct processing_module *mod = sof_heap_alloc(mod_heap, flags, sizeof(*mod), 0); | ||
|
|
||
| if (!mod) { | ||
| comp_cl_err(drv, "failed to allocate memory for module"); | ||
| goto emod; | ||
| } | ||
|
|
||
| memset(mod, 0, sizeof(*mod)); | ||
| mod->priv.resources.heap = mod_heap; | ||
| mod->priv.resources.heap_mem = mod_heap_mem; | ||
|
|
||
| /* | ||
| * comp_alloc() always allocated dev uncached. Would be difficult to optimize. Only | ||
| * if the whole currently active topology is running on the primary core, then it | ||
| * can be cached. Effectively it can be only cached in single-core configurations. | ||
| */ | ||
| struct comp_dev *dev = sof_heap_alloc(mod_heap, SOF_MEM_FLAG_COHERENT, sizeof(*dev), 0); | ||
|
|
||
| if (!dev) { | ||
| comp_cl_err(drv, "failed to allocate memory for comp_dev"); | ||
| goto err; | ||
| } | ||
|
|
||
| memset(dev, 0, sizeof(*dev)); | ||
| comp_init(drv, dev, sizeof(*dev)); | ||
| dev->ipc_config = *config; | ||
|
|
||
| mod->dev = dev; | ||
|
|
||
| return mod; | ||
|
|
||
| err: | ||
| sof_heap_free(mod_heap, mod); | ||
| emod: | ||
| rfree(mod_heap_mem); | ||
|
|
||
| return NULL; | ||
| } | ||
|
|
||
| static void module_adapter_mem_free(struct processing_module *mod) | ||
| { | ||
| struct k_heap *mod_heap = mod->priv.resources.heap; | ||
| void *mem = mod->priv.resources.heap_mem; | ||
|
|
||
| #if CONFIG_IPC_MAJOR_4 | ||
| sof_heap_free(mod_heap, mod->priv.cfg.input_pins); | ||
| #endif | ||
| sof_heap_free(mod_heap, mod->dev); | ||
|
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 we assume mod can be null and that's why it's checked earlier, then this line should also be inside that if to avoid a potential null pointer dereference. |
||
| sof_heap_free(mod_heap, mod); | ||
| rfree(mem); | ||
| } | ||
| #endif | ||
|
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. After this much code, it's good to add a comment explaining what this block depends on, especially since there are more |
||
|
|
||
| /* | ||
| * \brief Create a module adapter component. | ||
| * \param[in] drv - component driver pointer. | ||
|
|
@@ -61,8 +204,6 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv, | |
| void *mod_priv) | ||
| { | ||
| int ret; | ||
| struct comp_dev *dev; | ||
| struct processing_module *mod; | ||
| struct module_config *dst; | ||
| const struct module_interface *const interface = drv->adapter_ops; | ||
|
|
||
|
|
@@ -74,32 +215,17 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv, | |
| return NULL; | ||
| } | ||
|
|
||
| dev = comp_alloc(drv, sizeof(*dev)); | ||
| if (!dev) { | ||
| comp_cl_err(drv, "failed to allocate memory for comp_dev"); | ||
| return NULL; | ||
| } | ||
| dev->ipc_config = *config; | ||
|
|
||
| /* allocate module information. | ||
| * for DP shared modules this struct must be accessible from all cores | ||
| * Unfortunately at this point there's no information of components the module | ||
| * will be bound to. So we need to allocate shared memory for each DP module | ||
| * To be removed when pipeline 2.0 is ready | ||
| */ | ||
| int flags = config->proc_domain == COMP_PROCESSING_DOMAIN_DP ? | ||
| SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER; | ||
| struct processing_module *mod = module_adapter_mem_alloc(drv, config); | ||
|
|
||
| mod = module_driver_heap_rzalloc(drv->user_heap, flags, sizeof(*mod)); | ||
| if (!mod) { | ||
| comp_err(dev, "failed to allocate memory for module"); | ||
| goto err; | ||
| } | ||
| if (!mod) | ||
| return NULL; | ||
|
|
||
| dst = &mod->priv.cfg; | ||
|
|
||
| module_set_private_data(mod, mod_priv); | ||
| mod->dev = dev; | ||
|
|
||
| struct comp_dev *dev = mod->dev; | ||
|
|
||
| dev->mod = mod; | ||
|
|
||
| list_init(&mod->raw_data_buffers_list); | ||
|
|
@@ -178,13 +304,10 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv, | |
|
|
||
| comp_dbg(dev, "done"); | ||
| return dev; | ||
|
|
||
| err: | ||
| #if CONFIG_IPC_MAJOR_4 | ||
| if (mod) | ||
| rfree(mod->priv.cfg.input_pins); | ||
| #endif | ||
| rfree(mod); | ||
| rfree(dev); | ||
| module_adapter_mem_free(mod); | ||
|
|
||
| return NULL; | ||
| } | ||
| EXPORT_SYMBOL(module_adapter_new); | ||
|
|
@@ -542,11 +665,9 @@ int module_adapter_params(struct comp_dev *dev, struct sof_ipc_stream_params *pa | |
| #endif | ||
|
|
||
| /* allocate stream_params each time */ | ||
| if (mod->stream_params) | ||
| rfree(mod->stream_params); | ||
| mod_free(mod, mod->stream_params); | ||
|
|
||
| mod->stream_params = rzalloc(SOF_MEM_FLAG_USER, | ||
| sizeof(*mod->stream_params) + params->ext_data_length); | ||
| mod->stream_params = mod_alloc(mod, sizeof(*mod->stream_params) + params->ext_data_length); | ||
| if (!mod->stream_params) | ||
| return -ENOMEM; | ||
|
|
||
|
|
@@ -1248,7 +1369,7 @@ int module_adapter_reset(struct comp_dev *dev) | |
| buffer_zero(buffer); | ||
| } | ||
|
|
||
| rfree(mod->stream_params); | ||
| mod_free(mod, mod->stream_params); | ||
| mod->stream_params = NULL; | ||
|
|
||
| comp_dbg(dev, "done"); | ||
|
|
@@ -1280,15 +1401,10 @@ void module_adapter_free(struct comp_dev *dev) | |
| buffer_free(buffer); | ||
| } | ||
|
|
||
| mod_free(mod, mod->stream_params); | ||
| mod_free_all(mod); | ||
|
|
||
| #if CONFIG_IPC_MAJOR_4 | ||
| rfree(mod->priv.cfg.input_pins); | ||
| #endif | ||
|
|
||
| rfree(mod->stream_params); | ||
softwarecki marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| rfree(mod); | ||
| rfree(dev); | ||
| module_adapter_mem_free(mod); | ||
| } | ||
| EXPORT_SYMBOL(module_adapter_free); | ||
|
|
||
|
|
||
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 bit looks ugly in middle of module_adapter.c How about set HOST_PAGE_SIZE to CONFIG_MM_DRV_PAGE_SIZE if it is used, remove this bit and use HOST_PAGE_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.
@kv2019i
HOST_PAGE_SIZEis host's page size, we should use DSP's page size - as long as available. AndHOST_PAGE_SIZEis always defined, so I wouldn't redefine it.