Skip to content

Commit 6012f09

Browse files
committed
audio: module-adapter: add two system calls
Add two syscall functions to allocate and map, and to unmap vregion for userspace modules. For now only used for DP modules. Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
1 parent ca15f74 commit 6012f09

4 files changed

Lines changed: 105 additions & 10 deletions

File tree

src/audio/buffers/comp_buffer.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <sof/audio/sink_api.h>
1212
#include <sof/audio/source_api.h>
1313
#include <sof/audio/sink_source_utils.h>
14+
#include <sof/audio/module_adapter/module/generic.h>
1415
#include <rtos/userspace_helper.h>
1516
#include <sof/common.h>
1617
#include <rtos/interrupt.h>
@@ -165,8 +166,7 @@ static void comp_buffer_free(struct sof_audio_buffer *audio_buffer)
165166

166167
if (alloc && alloc->vreg) {
167168
vregion_free(alloc->vreg, buffer);
168-
if (!vregion_put(alloc->vreg))
169-
rfree(alloc);
169+
module_adapter_vreg_free(alloc);
170170
} else {
171171
sof_heap_free(alloc ? alloc->heap : NULL, buffer);
172172
}

src/audio/module_adapter/module_adapter.c

Lines changed: 94 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,80 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv,
5858
#define PAGE_SZ HOST_PAGE_SIZE
5959
#endif
6060

61-
static struct vregion *module_adapter_dp_heap_new(const struct comp_ipc_config *config,
62-
size_t *heap_size)
61+
struct vregion *z_impl_module_adapter_vreg_new(const struct comp_ipc_config *config,
62+
uintptr_t *vreg_start, size_t *vreg_size)
6363
{
6464
/* src-lite with 8 channels has been seen allocating 14k in one go */
6565
/* FIXME: the size will be derived from configuration */
6666
const size_t buf_size = 28 * 1024;
67+
struct vregion *vr = vregion_create(buf_size);
6768

68-
return vregion_create(buf_size);
69+
if (!vr)
70+
return NULL;
71+
72+
#ifdef CONFIG_SOF_USERSPACE_LL
73+
vregion_mem_info(vr, vreg_size, vreg_start);
74+
75+
/*
76+
* In the userspace LL case allocations are also performed by the
77+
* userspace IPC thread, which is also the one, executing this syscall
78+
*/
79+
struct k_mem_partition part = {
80+
.start = *vreg_start,
81+
.size = *vreg_size,
82+
.attr = K_MEM_PARTITION_P_RW_U_RW | XTENSA_MMU_CACHED_WB,
83+
};
84+
int ret = k_mem_domain_add_partition(zephyr_ll_mem_domain(), &part);
85+
86+
if (ret < 0) {
87+
vregion_put(vr);
88+
return NULL;
89+
}
90+
91+
part.start = (uintptr_t)sys_cache_uncached_ptr_get((void *)part.start);
92+
part.attr = K_MEM_PARTITION_P_RW_U_RW;
93+
94+
ret = k_mem_domain_add_partition(zephyr_ll_mem_domain(), &part);
95+
if (ret < 0) {
96+
vregion_put(vr);
97+
return NULL;
98+
}
99+
#else
100+
ARG_UNUSED(vreg_start);
101+
ARG_UNUSED(vreg_size);
102+
#endif
103+
104+
return vr;
105+
}
106+
107+
void z_impl_module_adapter_vreg_unmap(const struct mod_alloc_ctx *alloc)
108+
{
109+
#ifdef CONFIG_SOF_USERSPACE_LL
110+
struct k_mem_partition part = {
111+
.start = alloc->vreg_start,
112+
.size = alloc->vreg_size,
113+
.attr = K_MEM_PARTITION_P_RW_U_RW | XTENSA_MMU_CACHED_WB,
114+
};
115+
116+
k_mem_domain_remove_partition(zephyr_ll_mem_domain(), &part);
117+
118+
part.start = (uintptr_t)sys_cache_uncached_ptr_get((void *)part.start);
119+
part.attr = K_MEM_PARTITION_P_RW_U_RW;
120+
121+
k_mem_domain_remove_partition(zephyr_ll_mem_domain(), &part);
122+
#else
123+
ARG_UNUSED(alloc);
124+
#endif
125+
}
126+
127+
void module_adapter_vreg_free(struct mod_alloc_ctx *alloc)
128+
{
129+
if (vregion_put(alloc->vreg))
130+
return;
131+
132+
module_adapter_vreg_unmap(alloc);
133+
134+
sof_heap_free(alloc->heap, alloc);
69135
}
70136

71137
static struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv,
@@ -84,11 +150,12 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
84150
*/
85151
uint32_t flags = config->proc_domain == COMP_PROCESSING_DOMAIN_DP ?
86152
SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER;
87-
size_t heap_size;
153+
size_t vreg_size;
154+
uintptr_t vreg_start;
88155

89156
if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP && IS_ENABLED(CONFIG_SOF_VREGIONS) &&
90157
IS_ENABLED(CONFIG_USERSPACE) && !IS_ENABLED(CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP)) {
91-
mod_vreg = module_adapter_dp_heap_new(config, &heap_size);
158+
mod_vreg = module_adapter_vreg_new(config, &vreg_start, &vreg_size);
92159
if (!mod_vreg) {
93160
comp_cl_err(drv, "Failed to allocate DP module heap / vregion");
94161
return NULL;
@@ -101,7 +168,6 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
101168
#else
102169
mod_heap = drv->user_heap;
103170
#endif
104-
heap_size = 0;
105171
mod_vreg = NULL;
106172
}
107173

@@ -125,6 +191,8 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
125191
memset(mod, 0, sizeof(*mod));
126192
alloc->heap = mod_heap;
127193
alloc->vreg = mod_vreg;
194+
alloc->vreg_start = vreg_start;
195+
alloc->vreg_size = vreg_size;
128196
mod->priv.resources.alloc = alloc;
129197
mod_resource_init(mod);
130198

@@ -165,6 +233,25 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
165233
return NULL;
166234
}
167235

236+
#ifdef CONFIG_USERSPACE
237+
#include <zephyr/internal/syscall_handler.h>
238+
struct vregion *z_vrfy_module_adapter_vreg_new(const struct comp_ipc_config *config,
239+
uintptr_t *vreg_start, size_t *vreg_size)
240+
{
241+
K_OOPS(K_SYSCALL_MEMORY_WRITE(vreg_start, sizeof(*vreg_start)));
242+
K_OOPS(K_SYSCALL_MEMORY_WRITE(vreg_size, sizeof(*vreg_size)));
243+
K_OOPS(K_SYSCALL_MEMORY_READ(config, sizeof(*config)));
244+
return z_impl_module_adapter_vreg_new(config, vreg_start, vreg_size);
245+
}
246+
#include <zephyr/syscalls/module_adapter_vreg_new_mrsh.c>
247+
void z_vrfy_module_adapter_vreg_unmap(const struct mod_alloc_ctx *alloc)
248+
{
249+
K_OOPS(K_SYSCALL_MEMORY_READ(alloc, sizeof(*alloc)));
250+
z_impl_module_adapter_vreg_unmap(alloc);
251+
}
252+
#include <zephyr/syscalls/module_adapter_vreg_unmap_mrsh.c>
253+
#endif
254+
168255
static void module_adapter_mem_free(struct processing_module *mod)
169256
{
170257
struct mod_alloc_ctx *alloc = mod->priv.resources.alloc;
@@ -182,8 +269,7 @@ static void module_adapter_mem_free(struct processing_module *mod)
182269

183270
vregion_free(mod_vreg, mod->dev);
184271
vregion_free(mod_vreg, mod);
185-
if (!vregion_put(mod_vreg))
186-
sof_heap_free(alloc->heap, alloc);
272+
module_adapter_vreg_free(alloc);
187273
} else {
188274
sof_heap_free(mod_heap, mod->dev);
189275
sof_heap_free(mod_heap, mod);

src/include/sof/audio/module_adapter/module/generic.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,11 +199,18 @@ void *z_impl_mod_balloc_align(struct processing_module *mod, size_t size, size_t
199199
#endif
200200
void mod_resource_init(struct processing_module *mod);
201201
void mod_heap_info(struct processing_module *mod, size_t *size, uintptr_t *start);
202+
void module_adapter_vreg_free(struct mod_alloc_ctx *alloc);
202203
#if defined(__ZEPHYR__) && defined(CONFIG_SOF_FULL_ZEPHYR_APPLICATION)
204+
__syscall struct vregion *module_adapter_vreg_new(const struct comp_ipc_config *config,
205+
uintptr_t *vreg_start, size_t *vreg_size);
206+
__syscall void module_adapter_vreg_unmap(const struct mod_alloc_ctx *alloc);
203207
__syscall void *mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t size,
204208
size_t alignment);
205209
__syscall int mod_free(struct processing_module *mod, const void *ptr);
206210
#else
211+
struct vregion *z_impl_module_adapter_vreg_new(const struct comp_ipc_config *config,
212+
uintptr_t *vreg_start, size_t *vreg_size);
213+
void z_impl_module_adapter_vreg_unmap(const struct mod_alloc_ctx *alloc);
207214
void *z_impl_mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t size,
208215
size_t alignment);
209216
int z_impl_mod_free(struct processing_module *mod, const void *ptr);

zephyr/include/rtos/alloc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ size_t get_shared_buffer_heap_size(void);
167167
struct mod_alloc_ctx {
168168
struct k_heap *heap;
169169
struct vregion *vreg;
170+
uintptr_t vreg_start;
171+
size_t vreg_size;
170172
};
171173

172174
/**

0 commit comments

Comments
 (0)