please omit this patch and wait for my new patchset.

Thanks,
Lai

On 03/26/2014 10:41 PM, Lai Jiangshan wrote:
> worker_idr is always accessed in manager lock context currently.
> worker_idr is highly related to managers, it will be unlikely
> accessed in pool->lock only in future.
> 
> Signed-off-by: Lai Jiangshan <la...@cn.fujitsu.com>
> ---
>  kernel/workqueue.c |   34 ++++++----------------------------
>  1 files changed, 6 insertions(+), 28 deletions(-)
> 
> diff --git a/kernel/workqueue.c b/kernel/workqueue.c
> index 0c74979..f5b68a3 100644
> --- a/kernel/workqueue.c
> +++ b/kernel/workqueue.c
> @@ -123,8 +123,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.
> + * M: pool->manager_mutex protected.
>   *
>   * PL: wq_pool_mutex protected.
>   *
> @@ -163,7 +162,7 @@ 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 idr              worker_idr;     /* M: worker IDs and iteration 
> */
>  
>       struct workqueue_attrs  *attrs;         /* I: worker attributes */
>       struct hlist_node       hash_node;      /* PL: unbound_pool_hash node */
> @@ -339,16 +338,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]; \
> @@ -377,14 +366,14 @@ static void copy_workqueue_attrs(struct workqueue_attrs 
> *to,
>   * @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 either @pool->manager_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; })) { } \
> +             if (({ lockdep_assert_held(&pool->manager_mutex); false; })) { 
> } \
>               else
>  
>  /**
> @@ -1717,13 +1706,7 @@ static struct worker *create_worker(struct worker_pool 
> *pool)
>        * 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 = idr_alloc(&pool->worker_idr, NULL, 0, 0, GFP_KERNEL);
>       if (id < 0)
>               goto fail;
>  
> @@ -1765,18 +1748,13 @@ static struct worker *create_worker(struct 
> worker_pool *pool)
>               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);
>  
>       return worker;
>  
>  fail:
> -     if (id >= 0) {
> -             spin_lock_irq(&pool->lock);
> +     if (id >= 0)
>               idr_remove(&pool->worker_idr, id);
> -             spin_unlock_irq(&pool->lock);
> -     }
>       kfree(worker);
>       return NULL;
>  }

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to