workqueue - queue + drain
Martin Kaiser
lists at kaiser.cx
Thu Aug 11 12:03:51 EDT 2022
Dear all,
would you mind helping me understand how workers and workqueues act in a
seemingly simple scenario? I'm calling
queue_work(my_queue, my_worker)
to add a worker to a queue that was created by calling
create_singlethread_workqueue().
This goes into
queue_work
queue_work_on
...
if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))) {
__queue_work(cpu, wq, work);
ret = true;
}
... return false if __queue_work hasn't been called...
with
static void __queue_work(int cpu, struct workqueue_struct *wq, struct work_struct *work)
...
/* if draining, only works from the same workqueue are allowed */
if (unlikely(wq->flags & __WQ_DRAINING) &&
WARN_ON_ONCE(!is_chained_work(wq)))
return;
If drain_workqueue(my_queue) is running while
queue_work(my_queue, my_worker)
is called, my_worker will have WORK_STRUCT_PENDING_BIT set, but it's not
queued and no error is returned.
With WORK_STRUCT_PENDING_BIT set, all further attempts to
queue_work(my_queue, my_worker)
later, after draining is done, will fail.
This code has been unchanged since at least 4.14. Could anyone shed some
light on this, where am I getting things wrong?
Thanks and best regards,
Martin
More information about the Kernelnewbies
mailing list