work_cancel() used to return -ENOENT when the work structure was not
in the queue, and callers depend on that: aio_cancel() tears down the
AIO container (file_put() + aioc_free()) only when work_cancel()
reports success, because a work item that is not queued may already be
executing on a worker thread (see the comment in fs/aio/aio_cancel.c).
Since commit 6f72f5481d ("sched/wqueue: Refactor delayed and periodical
workqueue") work_cancel() returns OK unconditionally, and commit
d2e01b9055 ("sched/wqueue: harden custom queue lifecycle") kept that
behaviour and dropped -ENOENT from the function documentation. Under
SMP the LTP aio_cancel tests then free the aio container and its file
while the lpwork thread is still executing aio_write_worker() on it,
which ends in a page fault in file_write() (f_inode == NULL) and a
panic.
Return -ENOENT again when the work is not queued, and document it.
For the synchronous variant "not queued" alone does not tell whether
the callback is running: the worker scan does, so report OK when a
running callback was found and waited for, and -ENOENT only when the
work was neither queued nor running.
Assisted-by: Claude Code
Signed-off-by: raiden00pl <raiden00@railab.me>
Replace the local EINTR retry loop with
nxsem_wait_uninterruptible(). This keeps the master implementation
aligned with the semaphore API without changing cancellation behavior.
Keep the cleanup separate so release branches where the helper is
unavailable can use the lifecycle commit without a downstream
compatibility patch.
Assisted-by: Codex:GPT-5
Signed-off-by: DuoYuWang <thirteenking.wang@gmail.com>
Prevent work_queue_free() from destroying predefined queues or freeing a
custom queue from one of its own callbacks. Mark teardown under the queue
lock, reject new submissions, return pending work to its owner, and wait for
every worker before releasing queue resources.
Clean up partially created worker pools, reject invalid delays, safely
replace pending periodic work, and make synchronous cancellation wait for
every concurrent callback using the same work structure.
Tested on an STM32H7 PX4 FMUv6C with the matching ostest suite in Flat and
Protected kernel builds.
Assisted-by: Codex:GPT-5
Signed-off-by: DuoYuWang <thirteenking.wang@gmail.com>
This commit fixed windows compilation errors `struct
lp_wqueue_s/hp_wqueue_s has an illegal zero-sized array`.
Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com>
This commit fixed work_cancel_sync at a very rare boundary case. When a worker thread re-enqueues the work data structure during the execution of work, the user thread cannot directly dequeue the work in work_cancel_sync. Instead, it should wait until all workers' references to the work data structure have been eliminated after dequeuing.
Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com>
This commit refactors the logic of workqueue processing delayed and periodic work, and changes the timer to be set in `work_thread`. The improvements of this change are as follows:
- Fixed the memory reuse problem of the original periodic workqueue implementation.
- By removing the `wdog_s` structure in the `work_s` structure, the memory overhead of each `work_s` structure is reduced by about 30 bytes.
- Set the timer for each workqueue instead of each work, which improves system performance.
- Simplified the workqueue cancel logic.
Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com>
In NuttX, the dq and the list are two different implementations of the double-linked list. Comparing to the dq, the list implementation has less branch conditions such as checking whether the head or tail is NULL. In theory and practice, the list is more friendly to the CPU pipeline. This commit changed the dq to the list in the wqueue implementation.
Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com>
reason:
We decouple semcount from business logic
by using an independent counting variable,
which allows us to remove critical sections in many cases.
Signed-off-by: hujun5 <hujun5@xiaomi.com>
Return 1 to indicate the work was not cancelled.
Because it is currently being processed by work thread,
but wait for it to finish.
Signed-off-by: ligd <liguiding1@xiaomi.com>
Most tools used for compliance and SBOM generation use SPDX identifiers
This change brings us a step closer to an easy SBOM generation.
Signed-off-by: Alin Jerpelea <alin.jerpelea@sony.com>
sched implementation not depends on macro abstraction, so revert below commit:
This reverts commit 4e62d0005a
This reverts commit 0f0c370520
This reverts commit ad0efd04ee
Signed-off-by: chao an <anchao@lixiang.com>
Decouple the semcount and the work queue length.
Previous Problem:
If a work is queued and cancelled in high priority threads (or queued
by timer and cancelled by another high priority thread) before
work_thread runs, the queue operation will mark work_thread as ready to
run, but the cancel operation minus the semcount back to -1 and makes
wqueue->q empty. Then the work_thread still runs, found empty queue,
and wait sem again, then semcount becomes -2 (being minused by 1)
This can be done multiple times, then semcount can become very small
value. Test case to produce incorrect semcount:
high_priority_task()
{
for (int i = 0; i < 10000; i++)
{
work_queue(LPWORK, &work, worker, NULL, 0);
work_cancel(LPWORK, &work);
usleep(1);
}
/* Now the g_lpwork.sem.semcount is a value near -10000 */
}
With incorrect semcount, any queue operation when the work_thread is
busy, will only increase semcount and push work into queue, but cannot
trigger work_thread (semcount is negative but work_thread is not
waiting), then there will be more and more works left in queue while
the work_thread is waiting sem and cannot call them.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
The number of work entries will be inconsistent with semaphore count
if the work is canceled, in extreme case, semaphore count will overflow
and fallback to 0 the workqueue will stop scheduling the enqueue work.
Signed-off-by: chao an <anchao@xiaomi.com>
include/nuttx/wqueue.h:
libs/libc/wqueue/work_cancel.c:
libs/libc/wqueue/work_queue.c:
sched/wqueue/kwork_cancel.c:
sched/wqueue/kwork_queue.c:
* Fix spelling, grammar, and typos.
* Improve wording in a few areas.
* These changes affect comments only. No functional changes.