workqueue: Factor out work to worker assignment and collision handling
authorTejun Heo <tj@kernel.org>
Tue, 8 Aug 2023 01:57:25 +0000 (15:57 -1000)
committerTejun Heo <tj@kernel.org>
Tue, 8 Aug 2023 01:57:25 +0000 (15:57 -1000)
commit873eaca6eaf84b1d1ed5b7259308c6a4fca70fdc
tree9afddcb8aa7da3494482b3eed9cce5d18f96a212
parent63c5484e74952f60f5810256bd69814d167b8d22
workqueue: Factor out work to worker assignment and collision handling

The two work execution paths in worker_thread() and rescuer_thread() use
move_linked_works() to claim work items from @pool->worklist. Once claimed,
process_schedule_works() is called which invokes process_one_work() on each
work item. process_one_work() then uses find_worker_executing_work() to
detect and handle collisions - situations where the work item to be executed
is still running on another worker.

This works fine, but, to improve work execution locality, we want to
establish work to worker association earlier and know for sure that the
worker is going to excute the work once asssigned, which requires performing
collision handling earlier while trying to assign the work item to the
worker.

This patch introduces assign_work() which assigns a work item to a worker
using move_linked_works() and then performs collision handling. As collision
handling is handled earlier, process_one_work() no longer needs to worry
about them.

After the this patch, collision checks for linked work items are skipped,
which should be fine as they can't be queued multiple times concurrently.
For work items running from rescuers, the timing of collision handling may
change but the invariant that the work items go through collision handling
before starting execution does not.

This patch shouldn't cause noticeable behavior changes, especially given
that worker_thread() behavior remains the same.

Signed-off-by: Tejun Heo <tj@kernel.org>
kernel/workqueue.c