workqueue - queue + drain

Martin Kaiser lists at
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

This goes into

         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...


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) &&

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,


More information about the Kernelnewbies mailing list