Skip to content

Commit 81f434b

Browse files
committed
audio: pipeline: enable position reporting for user-space pipelines
Place the pipeline position lookup table in the sysuser memory partition and replace k_spinlock with a dynamically allocated k_mutex when CONFIG_SOF_USERSPACE_LL is enabled. Spinlocks disable interrupts which is a privileged operation unavailable from user-mode threads. The mutex pointer is stored in a separate APP_SYSUSER_BSS variable outside the SHARED_DATA struct so Zephyr's kernel object tracking can recognize it for syscall verification. Move pipeline_posn_init() from task_main_start() to primary_core_init() before platform_init(), so the mutex is allocated before ipc_user_init() grants thread access to it. In pipeline_posn_get(), bypass the sof_get() kernel singleton and access the shared structure directly when running in user-space. Grant the ipc_user_init thread access to the pipeline position mutex via new pipeline_posn_grant_access() helper. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
1 parent a1f8d73 commit 81f434b

5 files changed

Lines changed: 69 additions & 7 deletions

File tree

src/audio/pipeline/pipeline-graph.c

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <rtos/interrupt.h>
1313
#include <rtos/symbol.h>
1414
#include <rtos/alloc.h>
15+
#include <rtos/userspace_helper.h>
1516
#include <sof/lib/mm_heap.h>
1617
#include <sof/lib/uuid.h>
1718
#include <sof/compiler_attributes.h>
@@ -41,18 +42,33 @@ DECLARE_TR_CTX(pipe_tr, SOF_UUID(pipe_uuid), LOG_LEVEL_INFO);
4142
/* lookup table to determine busy/free pipeline metadata objects */
4243
struct pipeline_posn {
4344
bool posn_offset[PPL_POSN_OFFSETS]; /**< available offsets */
45+
#ifndef CONFIG_SOF_USERSPACE_LL
4446
struct k_spinlock lock; /**< lock mechanism */
47+
#endif
4548
};
4649
/* the pipeline position lookup table */
47-
static SHARED_DATA struct pipeline_posn pipeline_posn_shared;
50+
static APP_SYSUSER_BSS SHARED_DATA struct pipeline_posn pipeline_posn_shared;
51+
52+
#ifdef CONFIG_SOF_USERSPACE_LL
53+
/* Mutex pointer in user-accessible partition so user-space threads
54+
* can read the pointer for syscalls. Kept outside the SHARED_DATA
55+
* struct to avoid kernel object tracking issues.
56+
*/
57+
static APP_SYSUSER_BSS struct k_mutex *pipeline_posn_lock;
58+
#endif
4859

4960
/**
5061
* \brief Retrieves pipeline position structure.
5162
* \return Pointer to pipeline position structure.
5263
*/
5364
static inline struct pipeline_posn *pipeline_posn_get(void)
5465
{
66+
#ifdef CONFIG_SOF_USERSPACE_LL
67+
return platform_shared_get(&pipeline_posn_shared,
68+
sizeof(pipeline_posn_shared));
69+
#else
5570
return sof_get()->pipeline_posn;
71+
#endif
5672
}
5773

5874
/**
@@ -65,9 +81,14 @@ static inline int pipeline_posn_offset_get(uint32_t *posn_offset)
6581
struct pipeline_posn *pipeline_posn = pipeline_posn_get();
6682
int ret = -EINVAL;
6783
uint32_t i;
84+
85+
#ifdef CONFIG_SOF_USERSPACE_LL
86+
k_mutex_lock(pipeline_posn_lock, K_FOREVER);
87+
#else
6888
k_spinlock_key_t key;
6989

7090
key = k_spin_lock(&pipeline_posn->lock);
91+
#endif
7192

7293
for (i = 0; i < PPL_POSN_OFFSETS; ++i) {
7394
if (!pipeline_posn->posn_offset[i]) {
@@ -78,8 +99,11 @@ static inline int pipeline_posn_offset_get(uint32_t *posn_offset)
7899
}
79100
}
80101

81-
102+
#ifdef CONFIG_SOF_USERSPACE_LL
103+
k_mutex_unlock(pipeline_posn_lock);
104+
#else
82105
k_spin_unlock(&pipeline_posn->lock, key);
106+
#endif
83107

84108
return ret;
85109
}
@@ -92,22 +116,43 @@ static inline void pipeline_posn_offset_put(uint32_t posn_offset)
92116
{
93117
struct pipeline_posn *pipeline_posn = pipeline_posn_get();
94118
int i = posn_offset / sizeof(struct sof_ipc_stream_posn);
119+
120+
#ifdef CONFIG_SOF_USERSPACE_LL
121+
k_mutex_lock(pipeline_posn_lock, K_FOREVER);
122+
pipeline_posn->posn_offset[i] = false;
123+
k_mutex_unlock(pipeline_posn_lock);
124+
#else
95125
k_spinlock_key_t key;
96126

97127
key = k_spin_lock(&pipeline_posn->lock);
98-
99128
pipeline_posn->posn_offset[i] = false;
100-
101129
k_spin_unlock(&pipeline_posn->lock, key);
130+
#endif
102131
}
103132

104133
void pipeline_posn_init(struct sof *sof)
105134
{
106135
sof->pipeline_posn = platform_shared_get(&pipeline_posn_shared,
107136
sizeof(pipeline_posn_shared));
137+
#ifdef CONFIG_SOF_USERSPACE_LL
138+
pipeline_posn_lock = k_object_alloc(K_OBJ_MUTEX);
139+
if (!pipeline_posn_lock) {
140+
pipe_cl_err("pipeline posn mutex alloc failed");
141+
k_panic();
142+
}
143+
k_mutex_init(pipeline_posn_lock);
144+
#else
108145
k_spinlock_init(&sof->pipeline_posn->lock);
146+
#endif
109147
}
110148

149+
#ifdef CONFIG_SOF_USERSPACE_LL
150+
void pipeline_posn_grant_access(struct k_thread *thread)
151+
{
152+
k_thread_access_grant(thread, pipeline_posn_lock);
153+
}
154+
#endif
155+
111156
/* create new pipeline - returns pipeline id or negative error */
112157
struct pipeline *pipeline_new(struct k_heap *heap, uint32_t pipeline_id, uint32_t priority,
113158
uint32_t comp_id, struct create_pipeline_params *pparams)
@@ -138,12 +183,17 @@ struct pipeline *pipeline_new(struct k_heap *heap, uint32_t pipeline_id, uint32_
138183
p->pipeline_id = pipeline_id;
139184
p->status = COMP_STATE_INIT;
140185
p->trigger.cmd = COMP_TRIGGER_NO_ACTION;
186+
187+
#ifdef CONFIG_SOF_USERSPACE_LL
188+
LOG_WRN("pipeline trace settings cannot be copied");
189+
#else
141190
ret = memcpy_s(&p->tctx, sizeof(struct tr_ctx), &pipe_tr,
142191
sizeof(struct tr_ctx));
143192
if (ret < 0) {
144193
pipe_err(p, "failed to copy trace settings");
145194
goto free;
146195
}
196+
#endif
147197

148198
ret = pipeline_posn_offset_get(&p->posn_offset);
149199
if (ret < 0) {

src/include/sof/audio/pipeline.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,14 @@ int pipeline_complete(struct pipeline *p, struct comp_dev *source,
206206
*/
207207
void pipeline_posn_init(struct sof *sof);
208208

209+
#ifdef CONFIG_SOF_USERSPACE_LL
210+
/**
211+
* \brief Grants user-space thread access to pipeline position mutex.
212+
* \param[in] thread Thread to grant access to.
213+
*/
214+
void pipeline_posn_grant_access(struct k_thread *thread);
215+
#endif
216+
209217
/**
210218
* \brief Resets the pipeline and free runtime resources.
211219
* \param[in] p pipeline.

src/init/init.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <sof/schedule/dp_schedule.h>
3333
#include <sof/schedule/ll_schedule.h>
3434
#include <sof/schedule/ll_schedule_domain.h>
35+
#include <sof/audio/pipeline.h>
3536
#include <ipc/trace.h>
3637
#if CONFIG_IPC_MAJOR_4
3738
#include <ipc4/fw_reg.h>
@@ -222,6 +223,11 @@ __cold static int primary_core_init(int argc, char *argv[], struct sof *sof)
222223
zephyr_ll_user_resources_init();
223224
#endif
224225

226+
/* init pipeline position offsets - must be before platform_init()
227+
* which calls ipc_init() -> ipc_user_init() that needs the posn mutex.
228+
*/
229+
pipeline_posn_init(sof);
230+
225231
/* init the platform */
226232
if (platform_init(sof) < 0)
227233
sof_panic(SOF_IPC_PANIC_PLATFORM);

src/ipc/ipc-common.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,7 @@ __cold int ipc_user_init(void)
454454
user_grant_dma_access_all(&ipc_user_thread);
455455
user_access_to_mailbox(zephyr_ll_mem_domain(), &ipc_user_thread);
456456
zephyr_ll_grant_access(&ipc_user_thread);
457+
pipeline_posn_grant_access(&ipc_user_thread);
457458
k_mem_domain_add_thread(zephyr_ll_mem_domain(), &ipc_user_thread);
458459

459460
k_thread_cpu_pin(&ipc_user_thread, PLATFORM_PRIMARY_CORE_ID);

zephyr/wrapper.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,6 @@ int task_main_start(struct sof *sof)
176176
/* init default audio components */
177177
sys_comp_init(sof);
178178

179-
/* init pipeline position offsets */
180-
pipeline_posn_init(sof);
181-
182179
return 0;
183180
}
184181

0 commit comments

Comments
 (0)