]> www.infradead.org Git - users/hch/xfs.git/commitdiff
workqueue: Always queue work items to the newest PWQ for order workqueues
authorLai Jiangshan <jiangshan.ljs@antgroup.com>
Wed, 3 Jul 2024 09:27:41 +0000 (17:27 +0800)
committerTejun Heo <tj@kernel.org>
Mon, 15 Jul 2024 04:20:19 +0000 (18:20 -1000)
To ensure non-reentrancy, __queue_work() attempts to enqueue a work
item to the pool of the currently executing worker. This is not only
unnecessary for an ordered workqueue, where order inherently suggests
non-reentrancy, but it could also disrupt the sequence if the item is
not enqueued on the newest PWQ.

Just queue it to the newest PWQ and let order management guarantees
non-reentrancy.

Signed-off-by: Lai Jiangshan <jiangshan.ljs@antgroup.com>
Fixes: 4c065dbce1e8 ("workqueue: Enable unbound cpumask update on ordered workqueues")
Cc: stable@vger.kernel.org # v6.9+
Signed-off-by: Tejun Heo <tj@kernel.org>
(cherry picked from commit 74347be3edfd11277799242766edf844c43dd5d3)

kernel/workqueue.c

index 79a178500a77466564efaf2ac1489c804f93aaf8..e3ab09e70ba9a9b790c2cfe9c2da6d9b7be6bba3 100644 (file)
@@ -2274,9 +2274,13 @@ retry:
         * If @work was previously on a different pool, it might still be
         * running there, in which case the work needs to be queued on that
         * pool to guarantee non-reentrancy.
+        *
+        * For ordered workqueue, work items must be queued on the newest pwq
+        * for accurate order management.  Guaranteed order also guarantees
+        * non-reentrancy.  See the comments above unplug_oldest_pwq().
         */
        last_pool = get_work_pool(work);
-       if (last_pool && last_pool != pool) {
+       if (last_pool && last_pool != pool && !(wq->flags & __WQ_ORDERED)) {
                struct worker *worker;
 
                raw_spin_lock(&last_pool->lock);