]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - kernel/workqueue.c
Merge branches 'pm-sleep' and 'pm-cpufreq'
[karo-tx-linux.git] / kernel / workqueue.c
index a4bab46cd38e1ee177fe30bcf51d9d5861cac3ed..35974ac696007fadb8b4e35b9d0f37c8b6034747 100644 (file)
@@ -65,15 +65,12 @@ enum {
         * be executing on any CPU.  The pool behaves as an unbound one.
         *
         * Note that DISASSOCIATED should be flipped only while holding
-        * manager_mutex to avoid changing binding state while
-        * create_worker() is in progress.
+        * attach_mutex to avoid changing binding state while
+        * worker_attach_to_pool() is in progress.
         */
-       POOL_MANAGE_WORKERS     = 1 << 0,       /* need to manage workers */
        POOL_DISASSOCIATED      = 1 << 2,       /* cpu can't serve workers */
-       POOL_FREEZING           = 1 << 3,       /* freeze in progress */
 
        /* worker flags */
-       WORKER_STARTED          = 1 << 0,       /* started */
        WORKER_DIE              = 1 << 1,       /* die die die */
        WORKER_IDLE             = 1 << 2,       /* is idle */
        WORKER_PREP             = 1 << 3,       /* preparing to run works */
@@ -124,8 +121,7 @@ enum {
  *    cpu or grabbing pool->lock is enough for read access.  If
  *    POOL_DISASSOCIATED is set, it's identical to L.
  *
- * MG: pool->manager_mutex and pool->lock protected.  Writes require both
- *     locks.  Reads can happen under either lock.
+ * A: pool->attach_mutex protected.
  *
  * PL: wq_pool_mutex protected.
  *
@@ -163,8 +159,11 @@ struct worker_pool {
 
        /* see manage_workers() for details on the two manager mutexes */
        struct mutex            manager_arb;    /* manager arbitration */
-       struct mutex            manager_mutex;  /* manager exclusion */
-       struct idr              worker_idr;     /* MG: worker IDs and iteration */
+       struct mutex            attach_mutex;   /* attach/detach exclusion */
+       struct list_head        workers;        /* A: attached workers */
+       struct completion       *detach_completion; /* all workers detached */
+
+       struct ida              worker_ida;     /* worker IDs for task name */
 
        struct workqueue_attrs  *attrs;         /* I: worker attributes */
        struct hlist_node       hash_node;      /* PL: unbound_pool_hash node */
@@ -340,16 +339,6 @@ static void copy_workqueue_attrs(struct workqueue_attrs *to,
                           lockdep_is_held(&wq->mutex),                 \
                           "sched RCU or wq->mutex should be held")
 
-#ifdef CONFIG_LOCKDEP
-#define assert_manager_or_pool_lock(pool)                              \
-       WARN_ONCE(debug_locks &&                                        \
-                 !lockdep_is_held(&(pool)->manager_mutex) &&           \
-                 !lockdep_is_held(&(pool)->lock),                      \
-                 "pool->manager_mutex or ->lock should be held")
-#else
-#define assert_manager_or_pool_lock(pool)      do { } while (0)
-#endif
-
 #define for_each_cpu_worker_pool(pool, cpu)                            \
        for ((pool) = &per_cpu(cpu_worker_pools, cpu)[0];               \
             (pool) < &per_cpu(cpu_worker_pools, cpu)[NR_STD_WORKER_POOLS]; \
@@ -375,17 +364,16 @@ static void copy_workqueue_attrs(struct workqueue_attrs *to,
 /**
  * for_each_pool_worker - iterate through all workers of a worker_pool
  * @worker: iteration cursor
- * @wi: integer used for iteration
  * @pool: worker_pool to iterate workers of
  *
- * This must be called with either @pool->manager_mutex or ->lock held.
+ * This must be called with @pool->attach_mutex.
  *
  * The if/else clause exists only for the lockdep assertion and can be
  * ignored.
  */
-#define for_each_pool_worker(worker, wi, pool)                         \
-       idr_for_each_entry(&(pool)->worker_idr, (worker), (wi))         \
-               if (({ assert_manager_or_pool_lock((pool)); false; })) { } \
+#define for_each_pool_worker(worker, pool)                             \
+       list_for_each_entry((worker), &(pool)->workers, node)           \
+               if (({ lockdep_assert_held(&pool->attach_mutex); false; })) { } \
                else
 
 /**
@@ -763,13 +751,6 @@ static bool need_to_create_worker(struct worker_pool *pool)
        return need_more_worker(pool) && !may_start_working(pool);
 }
 
-/* Do I need to be the manager? */
-static bool need_to_manage_workers(struct worker_pool *pool)
-{
-       return need_to_create_worker(pool) ||
-               (pool->flags & POOL_MANAGE_WORKERS);
-}
-
 /* Do we have too many workers and should some go away? */
 static bool too_many_workers(struct worker_pool *pool)
 {
@@ -791,8 +772,8 @@ static bool too_many_workers(struct worker_pool *pool)
  * Wake up functions.
  */
 
-/* Return the first worker.  Safe with preemption disabled */
-static struct worker *first_worker(struct worker_pool *pool)
+/* Return the first idle worker.  Safe with preemption disabled */
+static struct worker *first_idle_worker(struct worker_pool *pool)
 {
        if (unlikely(list_empty(&pool->idle_list)))
                return NULL;
@@ -811,7 +792,7 @@ static struct worker *first_worker(struct worker_pool *pool)
  */
 static void wake_up_worker(struct worker_pool *pool)
 {
-       struct worker *worker = first_worker(pool);
+       struct worker *worker = first_idle_worker(pool);
 
        if (likely(worker))
                wake_up_process(worker->task);
@@ -885,7 +866,7 @@ struct task_struct *wq_worker_sleeping(struct task_struct *task, int cpu)
         */
        if (atomic_dec_and_test(&pool->nr_running) &&
            !list_empty(&pool->worklist))
-               to_wakeup = first_worker(pool);
+               to_wakeup = first_idle_worker(pool);
        return to_wakeup ? to_wakeup->task : NULL;
 }
 
@@ -1621,70 +1602,6 @@ static void worker_leave_idle(struct worker *worker)
        list_del_init(&worker->entry);
 }
 
-/**
- * worker_maybe_bind_and_lock - try to bind %current to worker_pool and lock it
- * @pool: target worker_pool
- *
- * Bind %current to the cpu of @pool if it is associated and lock @pool.
- *
- * Works which are scheduled while the cpu is online must at least be
- * scheduled to a worker which is bound to the cpu so that if they are
- * flushed from cpu callbacks while cpu is going down, they are
- * guaranteed to execute on the cpu.
- *
- * This function is to be used by unbound workers and rescuers to bind
- * themselves to the target cpu and may race with cpu going down or
- * coming online.  kthread_bind() can't be used because it may put the
- * worker to already dead cpu and set_cpus_allowed_ptr() can't be used
- * verbatim as it's best effort and blocking and pool may be
- * [dis]associated in the meantime.
- *
- * This function tries set_cpus_allowed() and locks pool and verifies the
- * binding against %POOL_DISASSOCIATED which is set during
- * %CPU_DOWN_PREPARE and cleared during %CPU_ONLINE, so if the worker
- * enters idle state or fetches works without dropping lock, it can
- * guarantee the scheduling requirement described in the first paragraph.
- *
- * CONTEXT:
- * Might sleep.  Called without any lock but returns with pool->lock
- * held.
- *
- * Return:
- * %true if the associated pool is online (@worker is successfully
- * bound), %false if offline.
- */
-static bool worker_maybe_bind_and_lock(struct worker_pool *pool)
-__acquires(&pool->lock)
-{
-       while (true) {
-               /*
-                * The following call may fail, succeed or succeed
-                * without actually migrating the task to the cpu if
-                * it races with cpu hotunplug operation.  Verify
-                * against POOL_DISASSOCIATED.
-                */
-               if (!(pool->flags & POOL_DISASSOCIATED))
-                       set_cpus_allowed_ptr(current, pool->attrs->cpumask);
-
-               spin_lock_irq(&pool->lock);
-               if (pool->flags & POOL_DISASSOCIATED)
-                       return false;
-               if (task_cpu(current) == pool->cpu &&
-                   cpumask_equal(&current->cpus_allowed, pool->attrs->cpumask))
-                       return true;
-               spin_unlock_irq(&pool->lock);
-
-               /*
-                * We've raced with CPU hot[un]plug.  Give it a breather
-                * and retry migration.  cond_resched() is required here;
-                * otherwise, we might deadlock against cpu_stop trying to
-                * bring down the CPU on non-preemptive kernel.
-                */
-               cpu_relax();
-               cond_resched();
-       }
-}
-
 static struct worker *alloc_worker(void)
 {
        struct worker *worker;
@@ -1693,19 +1610,76 @@ static struct worker *alloc_worker(void)
        if (worker) {
                INIT_LIST_HEAD(&worker->entry);
                INIT_LIST_HEAD(&worker->scheduled);
+               INIT_LIST_HEAD(&worker->node);
                /* on creation a worker is in !idle && prep state */
                worker->flags = WORKER_PREP;
        }
        return worker;
 }
 
+/**
+ * worker_attach_to_pool() - attach a worker to a pool
+ * @worker: worker to be attached
+ * @pool: the target pool
+ *
+ * Attach @worker to @pool.  Once attached, the %WORKER_UNBOUND flag and
+ * cpu-binding of @worker are kept coordinated with the pool across
+ * cpu-[un]hotplugs.
+ */
+static void worker_attach_to_pool(struct worker *worker,
+                                  struct worker_pool *pool)
+{
+       mutex_lock(&pool->attach_mutex);
+
+       /*
+        * set_cpus_allowed_ptr() will fail if the cpumask doesn't have any
+        * online CPUs.  It'll be re-applied when any of the CPUs come up.
+        */
+       set_cpus_allowed_ptr(worker->task, pool->attrs->cpumask);
+
+       /*
+        * The pool->attach_mutex ensures %POOL_DISASSOCIATED remains
+        * stable across this function.  See the comments above the
+        * flag definition for details.
+        */
+       if (pool->flags & POOL_DISASSOCIATED)
+               worker->flags |= WORKER_UNBOUND;
+
+       list_add_tail(&worker->node, &pool->workers);
+
+       mutex_unlock(&pool->attach_mutex);
+}
+
+/**
+ * worker_detach_from_pool() - detach a worker from its pool
+ * @worker: worker which is attached to its pool
+ * @pool: the pool @worker is attached to
+ *
+ * Undo the attaching which had been done in worker_attach_to_pool().  The
+ * caller worker shouldn't access to the pool after detached except it has
+ * other reference to the pool.
+ */
+static void worker_detach_from_pool(struct worker *worker,
+                                   struct worker_pool *pool)
+{
+       struct completion *detach_completion = NULL;
+
+       mutex_lock(&pool->attach_mutex);
+       list_del(&worker->node);
+       if (list_empty(&pool->workers))
+               detach_completion = pool->detach_completion;
+       mutex_unlock(&pool->attach_mutex);
+
+       if (detach_completion)
+               complete(detach_completion);
+}
+
 /**
  * create_worker - create a new workqueue worker
  * @pool: pool the new worker will belong to
  *
- * Create a new worker which is bound to @pool.  The returned worker
- * can be started by calling start_worker() or destroyed using
- * destroy_worker().
+ * Create a new worker which is attached to @pool.  The new worker must be
+ * started by start_worker().
  *
  * CONTEXT:
  * Might sleep.  Does GFP_KERNEL allocations.
@@ -1719,19 +1693,8 @@ static struct worker *create_worker(struct worker_pool *pool)
        int id = -1;
        char id_buf[16];
 
-       lockdep_assert_held(&pool->manager_mutex);
-
-       /*
-        * ID is needed to determine kthread name.  Allocate ID first
-        * without installing the pointer.
-        */
-       idr_preload(GFP_KERNEL);
-       spin_lock_irq(&pool->lock);
-
-       id = idr_alloc(&pool->worker_idr, NULL, 0, 0, GFP_NOWAIT);
-
-       spin_unlock_irq(&pool->lock);
-       idr_preload_end();
+       /* ID is needed to determine kthread name */
+       id = ida_simple_get(&pool->worker_ida, 0, 0, GFP_KERNEL);
        if (id < 0)
                goto fail;
 
@@ -1758,33 +1721,14 @@ static struct worker *create_worker(struct worker_pool *pool)
        /* prevent userland from meddling with cpumask of workqueue workers */
        worker->task->flags |= PF_NO_SETAFFINITY;
 
-       /*
-        * set_cpus_allowed_ptr() will fail if the cpumask doesn't have any
-        * online CPUs.  It'll be re-applied when any of the CPUs come up.
-        */
-       set_cpus_allowed_ptr(worker->task, pool->attrs->cpumask);
-
-       /*
-        * The caller is responsible for ensuring %POOL_DISASSOCIATED
-        * remains stable across this function.  See the comments above the
-        * flag definition for details.
-        */
-       if (pool->flags & POOL_DISASSOCIATED)
-               worker->flags |= WORKER_UNBOUND;
-
-       /* successful, commit the pointer to idr */
-       spin_lock_irq(&pool->lock);
-       idr_replace(&pool->worker_idr, worker, worker->id);
-       spin_unlock_irq(&pool->lock);
+       /* successful, attach the worker to the pool */
+       worker_attach_to_pool(worker, pool);
 
        return worker;
 
 fail:
-       if (id >= 0) {
-               spin_lock_irq(&pool->lock);
-               idr_remove(&pool->worker_idr, id);
-               spin_unlock_irq(&pool->lock);
-       }
+       if (id >= 0)
+               ida_simple_remove(&pool->worker_ida, id);
        kfree(worker);
        return NULL;
 }
@@ -1800,7 +1744,6 @@ fail:
  */
 static void start_worker(struct worker *worker)
 {
-       worker->flags |= WORKER_STARTED;
        worker->pool->nr_workers++;
        worker_enter_idle(worker);
        wake_up_process(worker->task);
@@ -1818,8 +1761,6 @@ static int create_and_start_worker(struct worker_pool *pool)
 {
        struct worker *worker;
 
-       mutex_lock(&pool->manager_mutex);
-
        worker = create_worker(pool);
        if (worker) {
                spin_lock_irq(&pool->lock);
@@ -1827,8 +1768,6 @@ static int create_and_start_worker(struct worker_pool *pool)
                spin_unlock_irq(&pool->lock);
        }
 
-       mutex_unlock(&pool->manager_mutex);
-
        return worker ? 0 : -ENOMEM;
 }
 
@@ -1836,46 +1775,30 @@ static int create_and_start_worker(struct worker_pool *pool)
  * destroy_worker - destroy a workqueue worker
  * @worker: worker to be destroyed
  *
- * Destroy @worker and adjust @pool stats accordingly.
+ * Destroy @worker and adjust @pool stats accordingly.  The worker should
+ * be idle.
  *
  * CONTEXT:
- * spin_lock_irq(pool->lock) which is released and regrabbed.
+ * spin_lock_irq(pool->lock).
  */
 static void destroy_worker(struct worker *worker)
 {
        struct worker_pool *pool = worker->pool;
 
-       lockdep_assert_held(&pool->manager_mutex);
        lockdep_assert_held(&pool->lock);
 
        /* sanity check frenzy */
        if (WARN_ON(worker->current_work) ||
-           WARN_ON(!list_empty(&worker->scheduled)))
+           WARN_ON(!list_empty(&worker->scheduled)) ||
+           WARN_ON(!(worker->flags & WORKER_IDLE)))
                return;
 
-       if (worker->flags & WORKER_STARTED)
-               pool->nr_workers--;
-       if (worker->flags & WORKER_IDLE)
-               pool->nr_idle--;
-
-       /*
-        * Once WORKER_DIE is set, the kworker may destroy itself at any
-        * point.  Pin to ensure the task stays until we're done with it.
-        */
-       get_task_struct(worker->task);
+       pool->nr_workers--;
+       pool->nr_idle--;
 
        list_del_init(&worker->entry);
        worker->flags |= WORKER_DIE;
-
-       idr_remove(&pool->worker_idr, worker->id);
-
-       spin_unlock_irq(&pool->lock);
-
-       kthread_stop(worker->task);
-       put_task_struct(worker->task);
-       kfree(worker);
-
-       spin_lock_irq(&pool->lock);
+       wake_up_process(worker->task);
 }
 
 static void idle_worker_timeout(unsigned long __pool)
@@ -1884,7 +1807,7 @@ static void idle_worker_timeout(unsigned long __pool)
 
        spin_lock_irq(&pool->lock);
 
-       if (too_many_workers(pool)) {
+       while (too_many_workers(pool)) {
                struct worker *worker;
                unsigned long expires;
 
@@ -1892,13 +1815,12 @@ static void idle_worker_timeout(unsigned long __pool)
                worker = list_entry(pool->idle_list.prev, struct worker, entry);
                expires = worker->last_active + IDLE_WORKER_TIMEOUT;
 
-               if (time_before(jiffies, expires))
+               if (time_before(jiffies, expires)) {
                        mod_timer(&pool->idle_timer, expires);
-               else {
-                       /* it's been idle for too long, wake up manager */
-                       pool->flags |= POOL_MANAGE_WORKERS;
-                       wake_up_worker(pool);
+                       break;
                }
+
+               destroy_worker(worker);
        }
 
        spin_unlock_irq(&pool->lock);
@@ -2016,44 +1938,6 @@ restart:
        return true;
 }
 
-/**
- * maybe_destroy_worker - destroy workers which have been idle for a while
- * @pool: pool to destroy workers for
- *
- * Destroy @pool workers which have been idle for longer than
- * IDLE_WORKER_TIMEOUT.
- *
- * LOCKING:
- * spin_lock_irq(pool->lock) which may be released and regrabbed
- * multiple times.  Called only from manager.
- *
- * Return:
- * %false if no action was taken and pool->lock stayed locked, %true
- * otherwise.
- */
-static bool maybe_destroy_workers(struct worker_pool *pool)
-{
-       bool ret = false;
-
-       while (too_many_workers(pool)) {
-               struct worker *worker;
-               unsigned long expires;
-
-               worker = list_entry(pool->idle_list.prev, struct worker, entry);
-               expires = worker->last_active + IDLE_WORKER_TIMEOUT;
-
-               if (time_before(jiffies, expires)) {
-                       mod_timer(&pool->idle_timer, expires);
-                       break;
-               }
-
-               destroy_worker(worker);
-               ret = true;
-       }
-
-       return ret;
-}
-
 /**
  * manage_workers - manage worker pool
  * @worker: self
@@ -2083,8 +1967,6 @@ static bool manage_workers(struct worker *worker)
        bool ret = false;
 
        /*
-        * Managership is governed by two mutexes - manager_arb and
-        * manager_mutex.  manager_arb handles arbitration of manager role.
         * Anyone who successfully grabs manager_arb wins the arbitration
         * and becomes the manager.  mutex_trylock() on pool->manager_arb
         * failure while holding pool->lock reliably indicates that someone
@@ -2093,40 +1975,12 @@ static bool manage_workers(struct worker *worker)
         * grabbing manager_arb is responsible for actually performing
         * manager duties.  If manager_arb is grabbed and released without
         * actual management, the pool may stall indefinitely.
-        *
-        * manager_mutex is used for exclusion of actual management
-        * operations.  The holder of manager_mutex can be sure that none
-        * of management operations, including creation and destruction of
-        * workers, won't take place until the mutex is released.  Because
-        * manager_mutex doesn't interfere with manager role arbitration,
-        * it is guaranteed that the pool's management, while may be
-        * delayed, won't be disturbed by someone else grabbing
-        * manager_mutex.
         */
        if (!mutex_trylock(&pool->manager_arb))
                return ret;
 
-       /*
-        * With manager arbitration won, manager_mutex would be free in
-        * most cases.  trylock first without dropping @pool->lock.
-        */
-       if (unlikely(!mutex_trylock(&pool->manager_mutex))) {
-               spin_unlock_irq(&pool->lock);
-               mutex_lock(&pool->manager_mutex);
-               spin_lock_irq(&pool->lock);
-               ret = true;
-       }
-
-       pool->flags &= ~POOL_MANAGE_WORKERS;
-
-       /*
-        * Destroy and then create so that may_start_working() is true
-        * on return.
-        */
-       ret |= maybe_destroy_workers(pool);
        ret |= maybe_create_worker(pool);
 
-       mutex_unlock(&pool->manager_mutex);
        mutex_unlock(&pool->manager_arb);
        return ret;
 }
@@ -2314,6 +2168,11 @@ woke_up:
                spin_unlock_irq(&pool->lock);
                WARN_ON_ONCE(!list_empty(&worker->entry));
                worker->task->flags &= ~PF_WQ_WORKER;
+
+               set_task_comm(worker->task, "kworker/dying");
+               ida_simple_remove(&pool->worker_ida, worker->id);
+               worker_detach_from_pool(worker, pool);
+               kfree(worker);
                return 0;
        }
 
@@ -2361,9 +2220,6 @@ recheck:
 
        worker_set_flags(worker, WORKER_PREP, false);
 sleep:
-       if (unlikely(need_to_manage_workers(pool)) && manage_workers(worker))
-               goto recheck;
-
        /*
         * pool->lock is held and there's no work to process and no need to
         * manage, sleep.  Workers are woken up only while holding
@@ -2440,8 +2296,9 @@ repeat:
 
                spin_unlock_irq(&wq_mayday_lock);
 
-               /* migrate to the target cpu if possible */
-               worker_maybe_bind_and_lock(pool);
+               worker_attach_to_pool(rescuer, pool);
+
+               spin_lock_irq(&pool->lock);
                rescuer->pool = pool;
 
                /*
@@ -2454,6 +2311,11 @@ repeat:
                                move_linked_works(work, scheduled, &n);
 
                process_scheduled_works(rescuer);
+               spin_unlock_irq(&pool->lock);
+
+               worker_detach_from_pool(rescuer, pool);
+
+               spin_lock_irq(&pool->lock);
 
                /*
                 * Put the reference grabbed by send_mayday().  @pool won't
@@ -3422,6 +3284,7 @@ int workqueue_sysfs_register(struct workqueue_struct *wq)
                }
        }
 
+       dev_set_uevent_suppress(&wq_dev->dev, false);
        kobject_uevent(&wq_dev->dev.kobj, KOBJ_ADD);
        return 0;
 }
@@ -3550,9 +3413,10 @@ static int init_worker_pool(struct worker_pool *pool)
                    (unsigned long)pool);
 
        mutex_init(&pool->manager_arb);
-       mutex_init(&pool->manager_mutex);
-       idr_init(&pool->worker_idr);
+       mutex_init(&pool->attach_mutex);
+       INIT_LIST_HEAD(&pool->workers);
 
+       ida_init(&pool->worker_ida);
        INIT_HLIST_NODE(&pool->hash_node);
        pool->refcnt = 1;
 
@@ -3567,7 +3431,7 @@ static void rcu_free_pool(struct rcu_head *rcu)
 {
        struct worker_pool *pool = container_of(rcu, struct worker_pool, rcu);
 
-       idr_destroy(&pool->worker_idr);
+       ida_destroy(&pool->worker_ida);
        free_workqueue_attrs(pool->attrs);
        kfree(pool);
 }
@@ -3585,6 +3449,7 @@ static void rcu_free_pool(struct rcu_head *rcu)
  */
 static void put_unbound_pool(struct worker_pool *pool)
 {
+       DECLARE_COMPLETION_ONSTACK(detach_completion);
        struct worker *worker;
 
        lockdep_assert_held(&wq_pool_mutex);
@@ -3605,18 +3470,24 @@ static void put_unbound_pool(struct worker_pool *pool)
        /*
         * Become the manager and destroy all workers.  Grabbing
         * manager_arb prevents @pool's workers from blocking on
-        * manager_mutex.
+        * attach_mutex.
         */
        mutex_lock(&pool->manager_arb);
-       mutex_lock(&pool->manager_mutex);
-       spin_lock_irq(&pool->lock);
 
-       while ((worker = first_worker(pool)))
+       spin_lock_irq(&pool->lock);
+       while ((worker = first_idle_worker(pool)))
                destroy_worker(worker);
        WARN_ON(pool->nr_workers || pool->nr_idle);
-
        spin_unlock_irq(&pool->lock);
-       mutex_unlock(&pool->manager_mutex);
+
+       mutex_lock(&pool->attach_mutex);
+       if (!list_empty(&pool->workers))
+               pool->detach_completion = &detach_completion;
+       mutex_unlock(&pool->attach_mutex);
+
+       if (pool->detach_completion)
+               wait_for_completion(pool->detach_completion);
+
        mutex_unlock(&pool->manager_arb);
 
        /* shut down the timers */
@@ -3662,9 +3533,6 @@ static struct worker_pool *get_unbound_pool(const struct workqueue_attrs *attrs)
        if (!pool || init_worker_pool(pool) < 0)
                goto fail;
 
-       if (workqueue_freezing)
-               pool->flags |= POOL_FREEZING;
-
        lockdep_set_subclass(&pool->lock, 1);   /* see put_pwq() */
        copy_workqueue_attrs(pool->attrs, attrs);
 
@@ -3771,7 +3639,12 @@ static void pwq_adjust_max_active(struct pool_workqueue *pwq)
 
        spin_lock_irq(&pwq->pool->lock);
 
-       if (!freezable || !(pwq->pool->flags & POOL_FREEZING)) {
+       /*
+        * During [un]freezing, the caller is responsible for ensuring that
+        * this function is called at least once after @workqueue_freezing
+        * is updated and visible.
+        */
+       if (!freezable || !workqueue_freezing) {
                pwq->max_active = wq->saved_max_active;
 
                while (!list_empty(&pwq->delayed_works) &&
@@ -4103,17 +3976,13 @@ static void wq_update_unbound_numa(struct workqueue_struct *wq, int cpu,
         * Let's determine what needs to be done.  If the target cpumask is
         * different from wq's, we need to compare it to @pwq's and create
         * a new one if they don't match.  If the target cpumask equals
-        * wq's, the default pwq should be used.  If @pwq is already the
-        * default one, nothing to do; otherwise, install the default one.
+        * wq's, the default pwq should be used.
         */
        if (wq_calc_node_cpumask(wq->unbound_attrs, node, cpu_off, cpumask)) {
                if (cpumask_equal(cpumask, pwq->pool->attrs->cpumask))
                        goto out_unlock;
        } else {
-               if (pwq == wq->dfl_pwq)
-                       goto out_unlock;
-               else
-                       goto use_dfl_pwq;
+               goto use_dfl_pwq;
        }
 
        mutex_unlock(&wq->mutex);
@@ -4121,8 +3990,8 @@ static void wq_update_unbound_numa(struct workqueue_struct *wq, int cpu,
        /* create a new pwq */
        pwq = alloc_unbound_pwq(wq, target_attrs);
        if (!pwq) {
-               pr_warning("workqueue: allocation failed while updating NUMA affinity of \"%s\"\n",
-                          wq->name);
+               pr_warn("workqueue: allocation failed while updating NUMA affinity of \"%s\"\n",
+                       wq->name);
                mutex_lock(&wq->mutex);
                goto use_dfl_pwq;
        }
@@ -4599,28 +4468,27 @@ static void wq_unbind_fn(struct work_struct *work)
        int cpu = smp_processor_id();
        struct worker_pool *pool;
        struct worker *worker;
-       int wi;
 
        for_each_cpu_worker_pool(pool, cpu) {
                WARN_ON_ONCE(cpu != smp_processor_id());
 
-               mutex_lock(&pool->manager_mutex);
+               mutex_lock(&pool->attach_mutex);
                spin_lock_irq(&pool->lock);
 
                /*
-                * We've blocked all manager operations.  Make all workers
+                * We've blocked all attach/detach operations. Make all workers
                 * unbound and set DISASSOCIATED.  Before this, all workers
                 * except for the ones which are still executing works from
                 * before the last CPU down must be on the cpu.  After
                 * this, they may become diasporas.
                 */
-               for_each_pool_worker(worker, wi, pool)
+               for_each_pool_worker(worker, pool)
                        worker->flags |= WORKER_UNBOUND;
 
                pool->flags |= POOL_DISASSOCIATED;
 
                spin_unlock_irq(&pool->lock);
-               mutex_unlock(&pool->manager_mutex);
+               mutex_unlock(&pool->attach_mutex);
 
                /*
                 * Call schedule() so that we cross rq->lock and thus can
@@ -4660,9 +4528,8 @@ static void wq_unbind_fn(struct work_struct *work)
 static void rebind_workers(struct worker_pool *pool)
 {
        struct worker *worker;
-       int wi;
 
-       lockdep_assert_held(&pool->manager_mutex);
+       lockdep_assert_held(&pool->attach_mutex);
 
        /*
         * Restore CPU affinity of all workers.  As all idle workers should
@@ -4671,13 +4538,13 @@ static void rebind_workers(struct worker_pool *pool)
         * of all workers first and then clear UNBOUND.  As we're called
         * from CPU_ONLINE, the following shouldn't fail.
         */
-       for_each_pool_worker(worker, wi, pool)
+       for_each_pool_worker(worker, pool)
                WARN_ON_ONCE(set_cpus_allowed_ptr(worker->task,
                                                  pool->attrs->cpumask) < 0);
 
        spin_lock_irq(&pool->lock);
 
-       for_each_pool_worker(worker, wi, pool) {
+       for_each_pool_worker(worker, pool) {
                unsigned int worker_flags = worker->flags;
 
                /*
@@ -4729,9 +4596,8 @@ static void restore_unbound_workers_cpumask(struct worker_pool *pool, int cpu)
 {
        static cpumask_t cpumask;
        struct worker *worker;
-       int wi;
 
-       lockdep_assert_held(&pool->manager_mutex);
+       lockdep_assert_held(&pool->attach_mutex);
 
        /* is @cpu allowed for @pool? */
        if (!cpumask_test_cpu(cpu, pool->attrs->cpumask))
@@ -4743,7 +4609,7 @@ static void restore_unbound_workers_cpumask(struct worker_pool *pool, int cpu)
                return;
 
        /* as we're called from CPU_ONLINE, the following shouldn't fail */
-       for_each_pool_worker(worker, wi, pool)
+       for_each_pool_worker(worker, pool)
                WARN_ON_ONCE(set_cpus_allowed_ptr(worker->task,
                                                  pool->attrs->cpumask) < 0);
 }
@@ -4776,7 +4642,7 @@ static int workqueue_cpu_up_callback(struct notifier_block *nfb,
                mutex_lock(&wq_pool_mutex);
 
                for_each_pool(pool, pi) {
-                       mutex_lock(&pool->manager_mutex);
+                       mutex_lock(&pool->attach_mutex);
 
                        if (pool->cpu == cpu) {
                                spin_lock_irq(&pool->lock);
@@ -4788,7 +4654,7 @@ static int workqueue_cpu_up_callback(struct notifier_block *nfb,
                                restore_unbound_workers_cpumask(pool, cpu);
                        }
 
-                       mutex_unlock(&pool->manager_mutex);
+                       mutex_unlock(&pool->attach_mutex);
                }
 
                /* update NUMA affinity of unbound workqueues */
@@ -4887,24 +4753,14 @@ EXPORT_SYMBOL_GPL(work_on_cpu);
  */
 void freeze_workqueues_begin(void)
 {
-       struct worker_pool *pool;
        struct workqueue_struct *wq;
        struct pool_workqueue *pwq;
-       int pi;
 
        mutex_lock(&wq_pool_mutex);
 
        WARN_ON_ONCE(workqueue_freezing);
        workqueue_freezing = true;
 
-       /* set FREEZING */
-       for_each_pool(pool, pi) {
-               spin_lock_irq(&pool->lock);
-               WARN_ON_ONCE(pool->flags & POOL_FREEZING);
-               pool->flags |= POOL_FREEZING;
-               spin_unlock_irq(&pool->lock);
-       }
-
        list_for_each_entry(wq, &workqueues, list) {
                mutex_lock(&wq->mutex);
                for_each_pwq(pwq, wq)
@@ -4974,21 +4830,13 @@ void thaw_workqueues(void)
 {
        struct workqueue_struct *wq;
        struct pool_workqueue *pwq;
-       struct worker_pool *pool;
-       int pi;
 
        mutex_lock(&wq_pool_mutex);
 
        if (!workqueue_freezing)
                goto out_unlock;
 
-       /* clear FREEZING */
-       for_each_pool(pool, pi) {
-               spin_lock_irq(&pool->lock);
-               WARN_ON_ONCE(!(pool->flags & POOL_FREEZING));
-               pool->flags &= ~POOL_FREEZING;
-               spin_unlock_irq(&pool->lock);
-       }
+       workqueue_freezing = false;
 
        /* restore max_active and repopulate worklist */
        list_for_each_entry(wq, &workqueues, list) {
@@ -4998,7 +4846,6 @@ void thaw_workqueues(void)
                mutex_unlock(&wq->mutex);
        }
 
-       workqueue_freezing = false;
 out_unlock:
        mutex_unlock(&wq_pool_mutex);
 }
@@ -5033,7 +4880,7 @@ static void __init wq_numa_init(void)
        BUG_ON(!tbl);
 
        for_each_node(node)
-               BUG_ON(!alloc_cpumask_var_node(&tbl[node], GFP_KERNEL,
+               BUG_ON(!zalloc_cpumask_var_node(&tbl[node], GFP_KERNEL,
                                node_online(node) ? node : NUMA_NO_NODE));
 
        for_each_possible_cpu(cpu) {