@@ -98,53 +98,79 @@ struct user_worker {
9898 struct k_event event ;
9999};
100100
101- static struct user_worker worker ;
101+ static struct user_worker worker [ CONFIG_CORE_COUNT ] ;
102102
103- static int user_worker_get (void )
103+ static void sof_work_user_queue_init (struct k_work_user_q * work_q , k_thread_stack_t * stack ,
104+ size_t stack_size , int prio , const char * name )
104105{
105- if (worker .reference_count ) {
106- worker .reference_count ++ ;
106+ k_queue_init (& work_q -> queue );
107+
108+ /* Created worker thread will inherit object permissions and memory
109+ * domain configuration of the caller
110+ */
111+ k_thread_create (& work_q -> thread , stack , stack_size , z_work_user_q_main ,
112+ work_q , NULL , NULL , prio , K_USER | K_INHERIT_PERMS ,
113+ K_FOREVER );
114+ k_object_access_grant (& work_q -> queue , & work_q -> thread );
115+ if (name != NULL ) {
116+ k_thread_name_set (& work_q -> thread , name );
117+ }
118+
119+ ///k_thread_start(&work_q->thread);
120+ }
121+
122+ static int user_worker_get (int cpu )
123+ {
124+ if (worker [cpu ].reference_count ) {
125+ worker [cpu ].reference_count ++ ;
107126 return 0 ;
108127 }
109128
110- worker .stack_ptr = user_stack_allocate (CONFIG_SOF_USERSPACE_PROXY_WORKER_STACK_SIZE ,
129+ worker [ cpu ] .stack_ptr = user_stack_allocate (CONFIG_SOF_USERSPACE_PROXY_WORKER_STACK_SIZE ,
111130 K_USER );
112- if (!worker .stack_ptr ) {
131+ if (!worker [ cpu ] .stack_ptr ) {
113132 tr_err (& userspace_proxy_tr , "Userspace worker stack allocation failed." );
114133 return - ENOMEM ;
115134 }
116135
117- k_event_init (& worker .event );
118- k_work_user_queue_start (& worker .work_queue , worker .stack_ptr ,
136+ k_event_init (& worker [ cpu ] .event );
137+ sof_work_user_queue_init (& worker [ cpu ] .work_queue , worker [ cpu ] .stack_ptr ,
119138 CONFIG_SOF_USERSPACE_PROXY_WORKER_STACK_SIZE , 0 , NULL );
120139
121- worker .thread_id = k_work_user_queue_thread_get (& worker .work_queue );
140+ worker [cpu ].thread_id = k_work_user_queue_thread_get (& worker [cpu ].work_queue );
141+
142+ /* Pin worker thread to the same core as the module */
143+ k_thread_cpu_pin (worker [cpu ].thread_id , cpu );
144+
145+ k_thread_access_grant (worker [cpu ].thread_id , & worker [cpu ].event );
146+
147+ worker [cpu ].reference_count ++ ;
122148
123- k_thread_access_grant ( worker . thread_id , & worker . event );
149+ k_thread_start ( & worker [ cpu ]. work_queue . thread );
124150
125- worker .reference_count ++ ;
126151 return 0 ;
127152}
128153
129- static void user_worker_put (void )
154+ static void user_worker_put (int cpu )
130155{
131156 /* Module removed so decrement counter */
132- worker .reference_count -- ;
157+ worker [ cpu ] .reference_count -- ;
133158
134159 /* Free worker resources if no more active user space modules */
135- if (worker .reference_count == 0 ) {
136- k_thread_abort (worker .thread_id );
137- user_stack_free (worker .stack_ptr );
160+ if (worker [ cpu ] .reference_count == 0 ) {
161+ k_thread_abort (worker [ cpu ] .thread_id );
162+ user_stack_free (worker [ cpu ] .stack_ptr );
138163 }
139164}
140165#endif
141166
142167static int user_work_item_init (struct userspace_context * user_ctx , struct k_heap * user_heap )
143168{
169+ int cpu = cpu_get_id ();
144170 struct user_work_item * work_item = NULL ;
145171 int ret ;
146172
147- ret = user_worker_get ();
173+ ret = user_worker_get (cpu );
148174 if (ret )
149175 return ret ;
150176
@@ -154,14 +180,14 @@ static int user_work_item_init(struct userspace_context *user_ctx, struct k_heap
154180 */
155181 work_item = sof_heap_alloc (user_heap , SOF_MEM_FLAG_COHERENT , sizeof (* work_item ), 0 );
156182 if (!work_item ) {
157- user_worker_put ();
183+ user_worker_put (cpu );
158184 return - ENOMEM ;
159185 }
160186
161187 k_work_user_init (& work_item -> work_item , userspace_proxy_worker_handler );
162188
163189#if !IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
164- work_item -> event = & worker .event ;
190+ work_item -> event = & worker [ cpu ] .event ;
165191#endif
166192 work_item -> params .context = user_ctx ;
167193 work_item -> params .mod = NULL ;
@@ -173,7 +199,7 @@ static int user_work_item_init(struct userspace_context *user_ctx, struct k_heap
173199static void user_work_item_free (struct userspace_context * user_ctx , struct k_heap * user_heap )
174200{
175201 sof_heap_free (user_heap , user_ctx -> work_item );
176- user_worker_put ();
202+ user_worker_put (cpu_get_id () );
177203}
178204
179205static inline struct module_params * user_work_get_params (struct userspace_context * user_ctx )
@@ -193,7 +219,8 @@ static int userspace_proxy_invoke(struct userspace_context *user_ctx, uint32_t c
193219#if IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
194220 struct k_event * const event = user_ctx -> dp_event ;
195221#else
196- struct k_event * const event = & worker .event ;
222+ int cpu = cpu_get_id ();
223+ struct k_event * const event = & worker [cpu ].event ;
197224#endif
198225 struct module_params * params = user_work_get_params (user_ctx );
199226 const uintptr_t ipc_req_buf = (uintptr_t )MAILBOX_HOSTBOX_BASE ;
@@ -216,22 +243,24 @@ static int userspace_proxy_invoke(struct userspace_context *user_ctx, uint32_t c
216243
217244#if !IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
218245 /* Switch worker thread to module memory domain */
219- ret = k_mem_domain_add_thread (user_ctx -> comp_dom , worker .thread_id );
246+ ret = k_mem_domain_add_thread (user_ctx -> comp_dom , worker [ cpu ] .thread_id );
220247 if (ret < 0 ) {
221248 tr_err (& userspace_proxy_tr , "Failed to switch memory domain, error: %d" , ret );
222249 goto done ;
223250 }
224251
252+ #if 0
225253#ifdef CONFIG_SCHED_CPU_MASK
226254 /* Pin worker thread to the same core as the module */
227- ret = k_thread_cpu_pin (worker .thread_id , cpu_get_id () );
255+ ret = k_thread_cpu_pin (worker [ cpu ] .thread_id , cpu );
228256 if (ret < 0 ) {
229257 tr_err (& userspace_proxy_tr , "Failed to pin cpu, error: %d" , ret );
230258 goto done ;
231259 }
232260#endif
261+ #endif // 0
233262
234- ret = k_work_user_submit_to_queue (& worker .work_queue , & user_ctx -> work_item -> work_item );
263+ ret = k_work_user_submit_to_queue (& worker [ cpu ] .work_queue , & user_ctx -> work_item -> work_item );
235264 if (ret < 0 ) {
236265 tr_err (& userspace_proxy_tr , "Submit to queue error: %d" , ret );
237266 goto done ;
0 commit comments