Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/include/sof/schedule/ll_schedule_domain.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,16 @@ struct ll_schedule_domain *zephyr_domain_init(int clk);
struct k_thread *zephyr_domain_thread_tid(struct ll_schedule_domain *domain);
struct k_mem_domain *zephyr_ll_mem_domain(void);
#endif /* CONFIG_SOF_USERSPACE_LL */
#ifdef CONFIG_SOF_FULL_ZEPHYR_APPLICATION
__syscall int zephyr_ll_task_sem_alloc(struct task *task);
__syscall int zephyr_ll_task_sem_free(struct task *task);
#include <zephyr/syscalls/ll_schedule_domain.h>
#else
int z_impl_zephyr_ll_task_sem_alloc(struct task *task);
int z_impl_zephyr_ll_task_sem_free(struct task *task);
#define zephyr_ll_task_sem_alloc z_impl_zephyr_ll_task_sem_alloc
#define zephyr_ll_task_sem_free z_impl_zephyr_ll_task_sem_free
#endif /* CONFIG_SOF_FULL_ZEPHYR_APPLICATION */
#endif /* __ZEPHYR__ */

struct ll_schedule_domain *dma_multi_chan_domain_init(struct dma *dma_array,
Expand Down
120 changes: 115 additions & 5 deletions src/schedule/zephyr_ll.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ struct zephyr_ll {
struct zephyr_ll_pdata {
bool run;
bool freeing;
struct k_sem *sem_p;
#if !CONFIG_DYNAMIC_OBJECTS
struct k_sem sem;
#endif
};

#if CONFIG_SOF_USERSPACE_LL
Expand Down Expand Up @@ -136,7 +139,7 @@ static void zephyr_ll_task_done(struct zephyr_ll *sch,
* zephyr_ll_task_free() is trying to free this task. Complete
* it and signal the semaphore to let the function proceed
*/
k_sem_give(&pdata->sem);
k_sem_give(pdata->sem_p);

tr_info(&ll_tr, "task complete %p %pU", task, task->uid);
tr_info(&ll_tr, "num_tasks %d total_num_tasks %ld",
Expand Down Expand Up @@ -448,6 +451,98 @@ static int zephyr_ll_task_schedule_after(void *data, struct task *task, uint64_t
return zephyr_ll_task_schedule_common(sch, task, start, period, after, false);
}

#if CONFIG_DYNAMIC_OBJECTS
static struct list_item zephyr_ll_task_sem_list = LIST_INIT(zephyr_ll_task_sem_list);

struct zephyr_ll_task_sem {
struct task *task;
struct k_sem *sem;
struct list_item list;
};

int z_impl_zephyr_ll_task_sem_alloc(struct task *task)
{
struct zephyr_ll_pdata *pdata = task->priv_data;
struct zephyr_ll_task_sem *ts = rmalloc(SOF_MEM_FLAG_COHERENT, sizeof(*ts));

if (!ts)
return -ENOMEM;

ts->sem = k_object_alloc(K_OBJ_SEM);
if (!ts->sem) {
rfree(ts);
return -ENOMEM;
}

k_sem_init(ts->sem, 0, 1);

ts->task = task;
pdata->sem_p = ts->sem;
/* List is protected by IPC serialization */
list_item_append(&ts->list, &zephyr_ll_task_sem_list);

return 0;
}

int z_impl_zephyr_ll_task_sem_free(struct task *task)
{
struct zephyr_ll_pdata *pdata = task->priv_data;
struct list_item *list;
struct zephyr_ll_task_sem *ts;
bool found = false;

/* List is protected by IPC serialization */
list_for_item(list, &zephyr_ll_task_sem_list) {
ts = container_of(list, struct zephyr_ll_task_sem, list);
if (ts->task == task) {
found = true;
break;
}
}

if (!found)
return -ENOENT;

if (pdata->sem_p != ts->sem)
return -EINVAL;

list_item_del(list);
k_object_free(ts->sem);
rfree(ts);

return 0;
}

#ifdef CONFIG_USERSPACE
#include <zephyr/internal/syscall_handler.h>
static inline int z_vrfy_zephyr_ll_task_sem_alloc(struct task *task)
{
if (!task)
return -EINVAL;
K_OOPS(K_SYSCALL_MEMORY_WRITE(task, sizeof(*task)));
if (!task->priv_data)
return -EINVAL;
K_OOPS(K_SYSCALL_MEMORY_WRITE(task->priv_data, sizeof(struct zephyr_ll_pdata)));

return z_impl_zephyr_ll_task_sem_alloc(task);
}
#include <zephyr/syscalls/zephyr_ll_task_sem_alloc_mrsh.c>

static inline int z_vrfy_zephyr_ll_task_sem_free(struct task *task)
{
if (!task)
return -EINVAL;
K_OOPS(K_SYSCALL_MEMORY_WRITE(task, sizeof(*task)));
if (!task->priv_data)
return -EINVAL;
K_OOPS(K_SYSCALL_MEMORY_WRITE(task->priv_data, sizeof(struct zephyr_ll_pdata)));

return z_impl_zephyr_ll_task_sem_free(task);
}
#include <zephyr/syscalls/zephyr_ll_task_sem_free_mrsh.c>
#endif
#endif

/*
* This is synchronous - after this returns the object can be destroyed!
* Assertion: under Zephyr this is always called from a thread context!
Expand Down Expand Up @@ -505,10 +600,13 @@ static int zephyr_ll_task_free(void *data, struct task *task)

if (must_wait)
/* Wait for up to 100 periods */
k_sem_take(&pdata->sem, K_USEC(LL_TIMER_PERIOD_US * 100));
k_sem_take(pdata->sem_p, K_USEC(LL_TIMER_PERIOD_US * 100));

/* Protect against racing with schedule_task() */
zephyr_ll_lock(sch, &flags);
#if CONFIG_DYNAMIC_OBJECTS
zephyr_ll_task_sem_free(task);
#endif
task->priv_data = NULL;
sof_heap_free(sch->heap, pdata);
zephyr_ll_unlock(sch, &flags);
Expand Down Expand Up @@ -573,6 +671,7 @@ static void zephyr_ll_scheduler_free(void *data, uint32_t flags)
struct k_thread *zephyr_ll_init_context(void *data, struct task *task)
{
struct zephyr_ll *sch = data;
struct zephyr_ll_pdata *pdata = task->priv_data;
int ret;

/*
Expand All @@ -587,7 +686,7 @@ struct k_thread *zephyr_ll_init_context(void *data, struct task *task)
}

assert(!k_is_user_context());
k_thread_access_grant(zephyr_domain_thread_tid(sch->ll_domain), sch->lock);
k_thread_access_grant(zephyr_domain_thread_tid(sch->ll_domain), sch->lock, pdata->sem_p);

tr_dbg(&ll_tr, "granting access to lock %p for thread %p", sch->lock,
zephyr_domain_thread_tid(sch->ll_domain));
Expand Down Expand Up @@ -698,10 +797,21 @@ int zephyr_ll_task_init(struct task *task,

memset(pdata, 0, sizeof(*pdata));

k_sem_init(&pdata->sem, 0, 1);

task->priv_data = pdata;

#if CONFIG_DYNAMIC_OBJECTS
ret = zephyr_ll_task_sem_alloc(task);
if (ret < 0) {
sof_heap_free(heap, pdata);
task->priv_data = NULL;
return ret;
}
#else
pdata->sem_p = &pdata->sem;
#endif

k_sem_init(pdata->sem_p, 0, 1);

return 0;
}
EXPORT_SYMBOL(zephyr_ll_task_init);
Expand Down
1 change: 1 addition & 0 deletions zephyr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,7 @@ zephyr_library_sources_ifdef(CONFIG_SHELL
zephyr_syscall_header(${SOF_SRC_PATH}/include/sof/audio/module_adapter/module/generic.h)
zephyr_syscall_header(${SOF_SRC_PATH}/include/sof/lib/fast-get.h)
zephyr_syscall_header(${SOF_SRC_PATH}/include/sof/ipc/ipc_reply.h)
zephyr_syscall_header(${SOF_SRC_PATH}/include/sof/schedule/ll_schedule_domain.h)
zephyr_syscall_header(${SOF_SRC_PATH}/include/ipc4/handler.h)
zephyr_syscall_header(include/rtos/alloc.h)
zephyr_library_sources_ifdef(CONFIG_SOF_USERSPACE_INTERFACE_ALLOC syscall/alloc.c)
Expand Down
Loading