aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-03-12 14:30:04 -0400
committerTejun Heo <tj@kernel.org>2013-03-12 14:30:04 -0400
commit8864b4e59f7945a636eeb27671f10486149be6e6 (patch)
tree74382658daf648a612e0bda94cb161cac84f0523 /kernel
parentd2c1d40487bb1884be085c187233084f80df052d (diff)
workqueue: implement get/put_pwq()
Add pool_workqueue->refcnt along with get/put_pwq(). Both per-cpu and unbound pwqs have refcnts and any work item inserted on a pwq increments the refcnt which is dropped when the work item finishes. For per-cpu pwqs the base ref is never dropped and destroy_workqueue() frees the pwqs as before. For unbound ones, destroy_workqueue() simply drops the base ref on the first pwq. When the refcnt reaches zero, pwq_unbound_release_workfn() is scheduled on system_wq, which unlinks the pwq, puts the associated pool and frees the pwq and wq as necessary. This needs to be done from a work item as put_pwq() needs to be protected by pool->lock but release can't happen with the lock held - e.g. put_unbound_pool() involves blocking operations. Unbound pool->locks are marked with lockdep subclas 1 as put_pwq() will schedule the release work item on system_wq while holding the unbound pool's lock and triggers recursive locking warning spuriously. This will be used to implement dynamic creation and destruction of unbound pwqs. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/workqueue.c137
1 files changed, 114 insertions, 23 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 5ac846e0085e..7dd8e7bcec51 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -179,6 +179,7 @@ struct pool_workqueue {
179 struct workqueue_struct *wq; /* I: the owning workqueue */ 179 struct workqueue_struct *wq; /* I: the owning workqueue */
180 int work_color; /* L: current color */ 180 int work_color; /* L: current color */
181 int flush_color; /* L: flushing color */ 181 int flush_color; /* L: flushing color */
182 int refcnt; /* L: reference count */
182 int nr_in_flight[WORK_NR_COLORS]; 183 int nr_in_flight[WORK_NR_COLORS];
183 /* L: nr of in_flight works */ 184 /* L: nr of in_flight works */
184 int nr_active; /* L: nr of active works */ 185 int nr_active; /* L: nr of active works */
@@ -186,6 +187,15 @@ struct pool_workqueue {
186 struct list_head delayed_works; /* L: delayed works */ 187 struct list_head delayed_works; /* L: delayed works */
187 struct list_head pwqs_node; /* R: node on wq->pwqs */ 188 struct list_head pwqs_node; /* R: node on wq->pwqs */
188 struct list_head mayday_node; /* W: node on wq->maydays */ 189 struct list_head mayday_node; /* W: node on wq->maydays */
190
191 /*
192 * Release of unbound pwq is punted to system_wq. See put_pwq()
193 * and pwq_unbound_release_workfn() for details. pool_workqueue
194 * itself is also sched-RCU protected so that the first pwq can be
195 * determined without grabbing workqueue_lock.
196 */
197 struct work_struct unbound_release_work;
198 struct rcu_head rcu;
189} __aligned(1 << WORK_STRUCT_FLAG_BITS); 199} __aligned(1 << WORK_STRUCT_FLAG_BITS);
190 200
191/* 201/*
@@ -939,6 +949,45 @@ static void move_linked_works(struct work_struct *work, struct list_head *head,
939 *nextp = n; 949 *nextp = n;
940} 950}
941 951
952/**
953 * get_pwq - get an extra reference on the specified pool_workqueue
954 * @pwq: pool_workqueue to get
955 *
956 * Obtain an extra reference on @pwq. The caller should guarantee that
957 * @pwq has positive refcnt and be holding the matching pool->lock.
958 */
959static void get_pwq(struct pool_workqueue *pwq)
960{
961 lockdep_assert_held(&pwq->pool->lock);
962 WARN_ON_ONCE(pwq->refcnt <= 0);
963 pwq->refcnt++;
964}
965
966/**
967 * put_pwq - put a pool_workqueue reference
968 * @pwq: pool_workqueue to put
969 *
970 * Drop a reference of @pwq. If its refcnt reaches zero, schedule its
971 * destruction. The caller should be holding the matching pool->lock.
972 */
973static void put_pwq(struct pool_workqueue *pwq)
974{
975 lockdep_assert_held(&pwq->pool->lock);
976 if (likely(--pwq->refcnt))
977 return;
978 if (WARN_ON_ONCE(!(pwq->wq->flags & WQ_UNBOUND)))
979 return;
980 /*
981 * @pwq can't be released under pool->lock, bounce to
982 * pwq_unbound_release_workfn(). This never recurses on the same
983 * pool->lock as this path is taken only for unbound workqueues and
984 * the release work item is scheduled on a per-cpu workqueue. To
985 * avoid lockdep warning, unbound pool->locks are given lockdep
986 * subclass of 1 in get_unbound_pool().
987 */
988 schedule_work(&pwq->unbound_release_work);
989}
990
942static void pwq_activate_delayed_work(struct work_struct *work) 991static void pwq_activate_delayed_work(struct work_struct *work)
943{ 992{
944 struct pool_workqueue *pwq = get_work_pwq(work); 993 struct pool_workqueue *pwq = get_work_pwq(work);
@@ -970,9 +1019,9 @@ static void pwq_activate_first_delayed(struct pool_workqueue *pwq)
970 */ 1019 */
971static void pwq_dec_nr_in_flight(struct pool_workqueue *pwq, int color) 1020static void pwq_dec_nr_in_flight(struct pool_workqueue *pwq, int color)
972{ 1021{
973 /* ignore uncolored works */ 1022 /* uncolored work items don't participate in flushing or nr_active */
974 if (color == WORK_NO_COLOR) 1023 if (color == WORK_NO_COLOR)
975 return; 1024 goto out_put;
976 1025
977 pwq->nr_in_flight[color]--; 1026 pwq->nr_in_flight[color]--;
978 1027
@@ -985,11 +1034,11 @@ static void pwq_dec_nr_in_flight(struct pool_workqueue *pwq, int color)
985 1034
986 /* is flush in progress and are we at the flushing tip? */ 1035 /* is flush in progress and are we at the flushing tip? */
987 if (likely(pwq->flush_color != color)) 1036 if (likely(pwq->flush_color != color))
988 return; 1037 goto out_put;
989 1038
990 /* are there still in-flight works? */ 1039 /* are there still in-flight works? */
991 if (pwq->nr_in_flight[color]) 1040 if (pwq->nr_in_flight[color])
992 return; 1041 goto out_put;
993 1042
994 /* this pwq is done, clear flush_color */ 1043 /* this pwq is done, clear flush_color */
995 pwq->flush_color = -1; 1044 pwq->flush_color = -1;
@@ -1000,6 +1049,8 @@ static void pwq_dec_nr_in_flight(struct pool_workqueue *pwq, int color)
1000 */ 1049 */
1001 if (atomic_dec_and_test(&pwq->wq->nr_pwqs_to_flush)) 1050 if (atomic_dec_and_test(&pwq->wq->nr_pwqs_to_flush))
1002 complete(&pwq->wq->first_flusher->done); 1051 complete(&pwq->wq->first_flusher->done);
1052out_put:
1053 put_pwq(pwq);
1003} 1054}
1004 1055
1005/** 1056/**
@@ -1122,6 +1173,7 @@ static void insert_work(struct pool_workqueue *pwq, struct work_struct *work,
1122 /* we own @work, set data and link */ 1173 /* we own @work, set data and link */
1123 set_work_pwq(work, pwq, extra_flags); 1174 set_work_pwq(work, pwq, extra_flags);
1124 list_add_tail(&work->entry, head); 1175 list_add_tail(&work->entry, head);
1176 get_pwq(pwq);
1125 1177
1126 /* 1178 /*
1127 * Ensure either worker_sched_deactivated() sees the above 1179 * Ensure either worker_sched_deactivated() sees the above
@@ -3301,6 +3353,7 @@ static struct worker_pool *get_unbound_pool(const struct workqueue_attrs *attrs)
3301 if (!pool || init_worker_pool(pool) < 0) 3353 if (!pool || init_worker_pool(pool) < 0)
3302 goto fail; 3354 goto fail;
3303 3355
3356 lockdep_set_subclass(&pool->lock, 1); /* see put_pwq() */
3304 copy_workqueue_attrs(pool->attrs, attrs); 3357 copy_workqueue_attrs(pool->attrs, attrs);
3305 3358
3306 if (worker_pool_assign_id(pool) < 0) 3359 if (worker_pool_assign_id(pool) < 0)
@@ -3329,7 +3382,41 @@ fail:
3329 return NULL; 3382 return NULL;
3330} 3383}
3331 3384
3332/* initialize @pwq which interfaces with @pool for @wq and link it in */ 3385static void rcu_free_pwq(struct rcu_head *rcu)
3386{
3387 kmem_cache_free(pwq_cache,
3388 container_of(rcu, struct pool_workqueue, rcu));
3389}
3390
3391/*
3392 * Scheduled on system_wq by put_pwq() when an unbound pwq hits zero refcnt
3393 * and needs to be destroyed.
3394 */
3395static void pwq_unbound_release_workfn(struct work_struct *work)
3396{
3397 struct pool_workqueue *pwq = container_of(work, struct pool_workqueue,
3398 unbound_release_work);
3399 struct workqueue_struct *wq = pwq->wq;
3400 struct worker_pool *pool = pwq->pool;
3401
3402 if (WARN_ON_ONCE(!(wq->flags & WQ_UNBOUND)))
3403 return;
3404
3405 spin_lock_irq(&workqueue_lock);
3406 list_del_rcu(&pwq->pwqs_node);
3407 spin_unlock_irq(&workqueue_lock);
3408
3409 put_unbound_pool(pool);
3410 call_rcu_sched(&pwq->rcu, rcu_free_pwq);
3411
3412 /*
3413 * If we're the last pwq going away, @wq is already dead and no one
3414 * is gonna access it anymore. Free it.
3415 */
3416 if (list_empty(&wq->pwqs))
3417 kfree(wq);
3418}
3419
3333static void init_and_link_pwq(struct pool_workqueue *pwq, 3420static void init_and_link_pwq(struct pool_workqueue *pwq,
3334 struct workqueue_struct *wq, 3421 struct workqueue_struct *wq,
3335 struct worker_pool *pool) 3422 struct worker_pool *pool)
@@ -3339,9 +3426,11 @@ static void init_and_link_pwq(struct pool_workqueue *pwq,
3339 pwq->pool = pool; 3426 pwq->pool = pool;
3340 pwq->wq = wq; 3427 pwq->wq = wq;
3341 pwq->flush_color = -1; 3428 pwq->flush_color = -1;
3429 pwq->refcnt = 1;
3342 pwq->max_active = wq->saved_max_active; 3430 pwq->max_active = wq->saved_max_active;
3343 INIT_LIST_HEAD(&pwq->delayed_works); 3431 INIT_LIST_HEAD(&pwq->delayed_works);
3344 INIT_LIST_HEAD(&pwq->mayday_node); 3432 INIT_LIST_HEAD(&pwq->mayday_node);
3433 INIT_WORK(&pwq->unbound_release_work, pwq_unbound_release_workfn);
3345 3434
3346 list_add_tail_rcu(&pwq->pwqs_node, &wq->pwqs); 3435 list_add_tail_rcu(&pwq->pwqs_node, &wq->pwqs);
3347} 3436}
@@ -3384,15 +3473,6 @@ static int alloc_and_link_pwqs(struct workqueue_struct *wq)
3384 return 0; 3473 return 0;
3385} 3474}
3386 3475
3387static void free_pwqs(struct workqueue_struct *wq)
3388{
3389 if (!(wq->flags & WQ_UNBOUND))
3390 free_percpu(wq->cpu_pwqs);
3391 else if (!list_empty(&wq->pwqs))
3392 kmem_cache_free(pwq_cache, list_first_entry(&wq->pwqs,
3393 struct pool_workqueue, pwqs_node));
3394}
3395
3396static int wq_clamp_max_active(int max_active, unsigned int flags, 3476static int wq_clamp_max_active(int max_active, unsigned int flags,
3397 const char *name) 3477 const char *name)
3398{ 3478{
@@ -3524,7 +3604,8 @@ void destroy_workqueue(struct workqueue_struct *wq)
3524 } 3604 }
3525 } 3605 }
3526 3606
3527 if (WARN_ON(pwq->nr_active) || 3607 if (WARN_ON(pwq->refcnt > 1) ||
3608 WARN_ON(pwq->nr_active) ||
3528 WARN_ON(!list_empty(&pwq->delayed_works))) { 3609 WARN_ON(!list_empty(&pwq->delayed_works))) {
3529 spin_unlock_irq(&workqueue_lock); 3610 spin_unlock_irq(&workqueue_lock);
3530 return; 3611 return;
@@ -3545,17 +3626,27 @@ void destroy_workqueue(struct workqueue_struct *wq)
3545 wq->rescuer = NULL; 3626 wq->rescuer = NULL;
3546 } 3627 }
3547 3628
3548 /* 3629 if (!(wq->flags & WQ_UNBOUND)) {
3549 * We're the sole accessor of @wq at this point. Directly access 3630 /*
3550 * the first pwq and put its pool. 3631 * The base ref is never dropped on per-cpu pwqs. Directly
3551 */ 3632 * free the pwqs and wq.
3552 if (wq->flags & WQ_UNBOUND) { 3633 */
3634 free_percpu(wq->cpu_pwqs);
3635 kfree(wq);
3636 } else {
3637 /*
3638 * We're the sole accessor of @wq at this point. Directly
3639 * access the first pwq and put the base ref. As both pwqs
3640 * and pools are sched-RCU protected, the lock operations
3641 * are safe. @wq will be freed when the last pwq is
3642 * released.
3643 */
3553 pwq = list_first_entry(&wq->pwqs, struct pool_workqueue, 3644 pwq = list_first_entry(&wq->pwqs, struct pool_workqueue,
3554 pwqs_node); 3645 pwqs_node);
3555 put_unbound_pool(pwq->pool); 3646 spin_lock_irq(&pwq->pool->lock);
3647 put_pwq(pwq);
3648 spin_unlock_irq(&pwq->pool->lock);
3556 } 3649 }
3557 free_pwqs(wq);
3558 kfree(wq);
3559} 3650}
3560EXPORT_SYMBOL_GPL(destroy_workqueue); 3651EXPORT_SYMBOL_GPL(destroy_workqueue);
3561 3652