Skip to content
  • Tejun Heo's avatar
    workqueue: reimplement CPU online rebinding to handle idle workers · 25511a47
    Tejun Heo authored
    
    
    Currently, if there are left workers when a CPU is being brough back
    online, the trustee kills all idle workers and scheduled rebind_work
    so that they re-bind to the CPU after the currently executing work is
    finished.  This works for busy workers because concurrency management
    doesn't try to wake up them from scheduler callbacks, which require
    the target task to be on the local run queue.  The busy worker bumps
    concurrency counter appropriately as it clears WORKER_UNBOUND from the
    rebind work item and it's bound to the CPU before returning to the
    idle state.
    
    To reduce CPU on/offlining overhead (as many embedded systems use it
    for powersaving) and simplify the code path, workqueue is planned to
    be modified to retain idle workers across CPU on/offlining.  This
    patch reimplements CPU online rebinding such that it can also handle
    idle workers.
    
    As noted earlier, due to the local wakeup requirement, rebinding idle
    workers is tricky.  All idle workers must be re-bound before scheduler
    callbacks are enabled.  This is achieved by interlocking idle
    re-binding.  Idle workers are requested to re-bind and then hold until
    all idle re-binding is complete so that no bound worker starts
    executing work item.  Only after all idle workers are re-bound and
    parked, CPU_ONLINE proceeds to release them and queue rebind work item
    to busy workers thus guaranteeing scheduler callbacks aren't invoked
    until all idle workers are ready.
    
    worker_rebind_fn() is renamed to busy_worker_rebind_fn() and
    idle_worker_rebind() for idle workers is added.  Rebinding logic is
    moved to rebind_workers() and now called from CPU_ONLINE after
    flushing trustee.  While at it, add CPU sanity check in
    worker_thread().
    
    Note that now a worker may become idle or the manager between trustee
    release and rebinding during CPU_ONLINE.  As the previous patch
    updated create_worker() so that it can be used by regular manager
    while unbound and this patch implements idle re-binding, this is safe.
    
    This prepares for removal of trustee and keeping idle workers across
    CPU hotplugs.
    
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Acked-by: default avatar"Rafael J. Wysocki" <rjw@sisk.pl>
    25511a47