Merge tag 'wq-for-6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 15 Jul 2024 23:51:22 +0000 (16:51 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 15 Jul 2024 23:51:22 +0000 (16:51 -0700)
Pull workqueue updates from Tejun Heo:

 - Lai fixed a bug where CPU hotplug and workqueue attribute changes
   race leaving some workqueues not fully updated. This involved
   refactoring and changing how online CPUs are tracked. The resulting
   code is cleaner.

 - Workqueue watchdog touch operation was causing too much cacheline
   contention on very large machines. Nicholas improved scalabililty by
   avoiding unnecessary global updates.

 - Code cleanups and minor rescuer behavior improvement.

 - The last commit 58629d4871e8 ("workqueue: Always queue work items to
   the newest PWQ for order workqueues") is a cherry-picked straggler
   commit from for-6.10-fixes, a fix for a bug which may not actually
   trigger.

* tag 'wq-for-6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq: (24 commits)
  workqueue: Always queue work items to the newest PWQ for order workqueues
  workqueue: Rename wq_update_pod() to unbound_wq_update_pwq()
  workqueue: Remove the arguments @hotplug_cpu and @online from wq_update_pod()
  workqueue: Remove the argument @cpu_going_down from wq_calc_pod_cpumask()
  workqueue: Remove the unneeded cpumask empty check in wq_calc_pod_cpumask()
  workqueue: Remove cpus_read_lock() from apply_wqattrs_lock()
  workqueue: Simplify wq_calc_pod_cpumask() with wq_online_cpumask
  workqueue: Add wq_online_cpumask
  workqueue: Init rescuer's affinities as the wq's effective cpumask
  workqueue: Put PWQ allocation and WQ enlistment in the same lock C.S.
  workqueue: Move kthread_flush_worker() out of alloc_and_link_pwqs()
  workqueue: Make rescuer initialization as the last step of the creation of a new wq
  workqueue: Register sysfs after the whole creation of the new wq
  workqueue: Simplify goto statement
  workqueue: Update cpumasks after only applying it successfully
  workqueue: Improve scalability of workqueue watchdog touch
  workqueue: wq_watchdog_touch is always called with valid CPU
  workqueue: Remove useless pool->dying_workers
  workqueue: Detach workers directly in idle_cull_fn()
  workqueue: Don't bind the rescuer in the last working cpu
  ...

1  2 
kernel/workqueue.c

@@@ -2738,31 -2732,8 +2733,28 @@@ static void worker_detach_from_pool(str
  
        /* clear leftover flags without pool->lock after it is detached */
        worker->flags &= ~(WORKER_UNBOUND | WORKER_REBOUND);
-       if (detach_completion)
-               complete(detach_completion);
  }
  
 +static int format_worker_id(char *buf, size_t size, struct worker *worker,
 +                          struct worker_pool *pool)
 +{
 +      if (worker->rescue_wq)
 +              return scnprintf(buf, size, "kworker/R-%s",
 +                               worker->rescue_wq->name);
 +
 +      if (pool) {
 +              if (pool->cpu >= 0)
 +                      return scnprintf(buf, size, "kworker/%d:%d%s",
 +                                       pool->cpu, worker->id,
 +                                       pool->attrs->nice < 0  ? "H" : "");
 +              else
 +                      return scnprintf(buf, size, "kworker/u%d:%d",
 +                                       pool->id, worker->id);
 +      } else {
 +              return scnprintf(buf, size, "kworker/dying");
 +      }
 +}
 +
  /**
   * create_worker - create a new workqueue worker
   * @pool: pool the new worker will belong to
@@@ -3367,10 -3333,9 +3350,8 @@@ woke_up
                raw_spin_unlock_irq(&pool->lock);
                set_pf_worker(false);
  
 -              set_task_comm(worker->task, "kworker/dying");
                ida_free(&pool->worker_ida, worker->id);
-               worker_detach_from_pool(worker);
                WARN_ON_ONCE(!list_empty(&worker->entry));
-               kfree(worker);
                return 0;
        }
  
@@@ -5558,9 -5500,10 +5516,11 @@@ static int wq_clamp_max_active(int max_
  static int init_rescuer(struct workqueue_struct *wq)
  {
        struct worker *rescuer;
 +      char id_buf[WORKER_ID_LEN];
        int ret;
  
+       lockdep_assert_held(&wq_pool_mutex);
        if (!(wq->flags & WQ_MEM_RECLAIM))
                return 0;