Skip to content

Commit 61bc445

Browse files
TaiJuWukartben
authored andcommitted
kernel: essential work queue should not stop
consider follow case ``` ZTEST(workqueue_api, test_k_work_queue_stop_sys_thread) { size_t i; struct k_work work; struct k_work_q work_q = {0}; struct k_work works[NUM_TEST_ITEMS]; struct k_work_queue_config cfg = { .name = "test_work_q", .no_yield = true, .essential = true, }; k_work_queue_start(&work_q, work_q_stack, K_THREAD_STACK_SIZEOF(work_q_stack), K_PRIO_PREEMPT(4), &cfg); zassert_true(k_work_queue_drain(&work_q, true) >= 0, "Failed to drain & plug work queue"); zassert_not_ok(k_work_queue_stop(&work_q, K_FOREVER), "Failed to stop work queue"); } ``` If we allow stop essential work queue, system will panic. Signed-off-by: TaiJu Wu <[email protected]>
1 parent 7d83155 commit 61bc445

File tree

3 files changed

+23
-0
lines changed

3 files changed

+23
-0
lines changed

include/zephyr/kernel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3930,6 +3930,7 @@ int k_work_queue_unplug(struct k_work_q *queue);
39303930
* @retval -EALREADY if the work queue was not started (or already stopped)
39313931
* @retval -EBUSY if the work queue is actively processing work items
39323932
* @retval -ETIMEDOUT if the work queue did not stop within the stipulated timeout
3933+
* @retval -ENOSUP if the work queue is essential
39333934
*/
39343935
int k_work_queue_stop(struct k_work_q *queue, k_timeout_t timeout);
39353936

kernel/work.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,11 @@ int k_work_queue_stop(struct k_work_q *queue, k_timeout_t timeout)
920920
__ASSERT_NO_MSG(queue);
921921

922922
SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_work_queue, stop, queue, timeout);
923+
924+
if (z_is_thread_essential(&queue->thread)) {
925+
return -ENOTSUP;
926+
}
927+
923928
k_spinlock_key_t key = k_spin_lock(&lock);
924929

925930
if (!flag_test(&queue->flags, K_WORK_QUEUE_STARTED_BIT)) {

tests/kernel/workq/work_queue/src/start_stop.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,23 @@ ZTEST(workqueue_api, test_k_work_queue_start_stop)
5656
"Succeeded to submit work item to non-initialized work queue");
5757
}
5858

59+
ZTEST(workqueue_api, test_k_work_queue_stop_sys_thread)
60+
{
61+
struct k_work_q work_q = {0};
62+
struct k_work_queue_config cfg = {
63+
.name = "test_work_q",
64+
.no_yield = true,
65+
.essential = true,
66+
};
67+
68+
k_work_queue_start(&work_q, work_q_stack, K_THREAD_STACK_SIZEOF(work_q_stack),
69+
K_PRIO_PREEMPT(4), &cfg);
70+
71+
zassert_true(k_work_queue_drain(&work_q, true) >= 0, "Failed to drain & plug work queue");
72+
zassert_equal(-ENOTSUP, k_work_queue_stop(&work_q, K_FOREVER), "Failed to stop work queue");
73+
}
74+
75+
5976
#define STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE)
6077

6178
static K_THREAD_STACK_DEFINE(run_stack, STACK_SIZE);

0 commit comments

Comments
 (0)