Topics

Use of k_work_submit_to_user_queue() with CONFIG_USERSPACE


Phil Erwin Jr
 

I have a work Q that will run in user state and attempting to send work to it.  This results in intermittent failures.  The issue I see
in my current test is that I have taken an interrupt while _current is the idle task.  The idle task has no resource pool, so the
'temporary memory allocation' fails.  No work request is saved.

It seems wrong to me that this API is making an allocation based upon the current thread, and is usable from interrupt handlers.
Every thread in the system would need a resource pool to allocate from.

Am I missing something here?

Phil


/**
 * @brief Submit a work item to a user mode workqueue
 *
 * Submits a work item to a workqueue that runs in user mode. A temporary
 * memory allocation is made from the caller's resource pool which is freed
 * once the worker thread consumes the k_work item. The workqueue
 * thread must have memory access to the k_work item being submitted. The caller
 * must have permission granted on the work_q parameter's queue object.
 *
 * Otherwise this works the same as k_work_submit_to_queue().
 *
 * @note Can be called by ISRs.
 *
 * @param work_q Address of workqueue.
 * @param work Address of work item.
 *
 * @retval -EBUSY if the work item was already in some workqueue
 * @retval -ENOMEM if no memory for thread resource pool allocation
 * @retval 0 Success
 * @req K-WORK-001
 */
static inline int k_work_submit_to_user_queue(struct k_work_q *work_q,
                          struct k_work *work)
{
    int ret = -EBUSY;

    H


Boie, Andrew P
 

This is a bug. I’ll spend some time on this today and get a GH issue opened.

 

Andrew

 

From: devel@... <devel@...> On Behalf Of phil.erwin@...
Sent: Thursday, January 23, 2020 9:14 AM
To: devel@...
Subject: [Zephyr-devel] Use of k_work_submit_to_user_queue() with CONFIG_USERSPACE

 

I have a work Q that will run in user state and attempting to send work to it.  This results in intermittent failures.  The issue I see
in my current test is that I have taken an interrupt while _current is the idle task.  The idle task has no resource pool, so the
'temporary memory allocation' fails.  No work request is saved.

It seems wrong to me that this API is making an allocation based upon the current thread, and is usable from interrupt handlers.
Every thread in the system would need a resource pool to allocate from.

Am I missing something here?

Phil


/**
 * @brief Submit a work item to a user mode workqueue
 *
 * Submits a work item to a workqueue that runs in user mode. A temporary
 * memory allocation is made from the caller's resource pool which is freed
 * once the worker thread consumes the k_work item. The workqueue
 * thread must have memory access to the k_work item being submitted. The caller
 * must have permission granted on the work_q parameter's queue object.
 *
 * Otherwise this works the same as k_work_submit_to_queue().
 *
 * @note Can be called by ISRs.
 *
 * @param work_q Address of workqueue.
 * @param work Address of work item.
 *
 * @retval -EBUSY if the work item was already in some workqueue
 * @retval -ENOMEM if no memory for thread resource pool allocation
 * @retval 0 Success
 * @req K-WORK-001
 */
static inline int k_work_submit_to_user_queue(struct k_work_q *work_q,
                          struct k_work *work)
{
    int ret = -EBUSY;

    H