Hi Tejun,

Today's linux-next merge of the workqueues tree got a conflict in
kernel/workqueue.c between commit e68035fb65de ("workqueue: convert to
idr_alloc()") from Linus' tree and commit fa1b54e69bc6 ("workqueue:
update synchronization rules on worker_pool_idr") from the workqueues
tree.

I fixed it up (as suggested - see below) and can carry the fix as
necessary (no action is required).

-- 
Cheers,
Stephen Rothwell                    s...@canb.auug.org.au

diff --cc kernel/workqueue.c
index 55fac5b,2ebd182..0000000
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@@ -456,40 -456,31 +456,32 @@@ static int worker_pool_assign_id(struc
  {
        int ret;
  
-       mutex_lock(&worker_pool_idr_mutex);
-       ret = idr_alloc(&worker_pool_idr, pool, 0, 0, GFP_KERNEL);
-       if (ret >= 0)
-               pool->id = ret;
-       mutex_unlock(&worker_pool_idr_mutex);
+       do {
 -              if (!idr_pre_get(&worker_pool_idr, GFP_KERNEL))
 -                      return -ENOMEM;
 -
++              idr_preload(GFP_KERNEL);
+               spin_lock_irq(&workqueue_lock);
 -              ret = idr_get_new(&worker_pool_idr, pool, &pool->id);
++              ret = idr_alloc(&worker_pool_idr, pool, 0, 0, GFP_NOWAIT);
++              if (ret >= 0)
++                      pool->id = ret;
+               spin_unlock_irq(&workqueue_lock);
++              idr_preload_end();
+       } while (ret == -EAGAIN);
  
 -      return ret;
 +      return ret < 0 ? ret : 0;
  }
  
- /*
-  * Lookup worker_pool by id.  The idr currently is built during boot and
-  * never modified.  Don't worry about locking for now.
+ /**
+  * first_pwq - return the first pool_workqueue of the specified workqueue
+  * @wq: the target workqueue
+  *
+  * This must be called either with workqueue_lock held or sched RCU read
+  * locked.  If the pwq needs to be used beyond the locking in effect, the
+  * caller is responsible for guaranteeing that the pwq stays online.
   */
- static struct worker_pool *worker_pool_by_id(int pool_id)
- {
-       return idr_find(&worker_pool_idr, pool_id);
- }
- 
- static struct worker_pool *get_std_worker_pool(int cpu, bool highpri)
- {
-       struct worker_pool *pools = std_worker_pools(cpu);
- 
-       return &pools[highpri];
- }
- 
- static struct pool_workqueue *get_pwq(unsigned int cpu,
-                                     struct workqueue_struct *wq)
+ static struct pool_workqueue *first_pwq(struct workqueue_struct *wq)
  {
-       if (!(wq->flags & WQ_UNBOUND)) {
-               if (likely(cpu < nr_cpu_ids))
-                       return per_cpu_ptr(wq->pool_wq.pcpu, cpu);
-       } else if (likely(cpu == WORK_CPU_UNBOUND))
-               return wq->pool_wq.single;
-       return NULL;
+       assert_rcu_or_wq_lock();
+       return list_first_or_null_rcu(&wq->pwqs, struct pool_workqueue,
+                                     pwqs_node);
  }
  
  static unsigned int work_color_to_flags(int color)

Attachment: pgp4mq6dple80.pgp
Description: PGP signature

Reply via email to