aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/workqueue.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-03-12 14:29:58 -0400
committerTejun Heo <tj@kernel.org>2013-03-12 14:29:58 -0400
commit49e3cf44df0663a521aa71e7667c52a9dbd0fce9 (patch)
tree6abded05fad30819d5f417cd967ffe468d25b629 /kernel/workqueue.c
parent30cdf2496d8ac2ef94b9b85f1891cf069490c8c4 (diff)
workqueue: replace for_each_pwq_cpu() with for_each_pwq()
Introduce for_each_pwq() which iterates all pool_workqueues of a workqueue using the recently added workqueue->pwqs list and replace for_each_pwq_cpu() usages with it. This is primarily to remove the single unbound CPU assumption from pwq iteration for the scheduled unbound pools with custom attributes support which would introduce multiple unbound pwqs per workqueue; however, it also simplifies iterator users. Note that pwq->pool initialization is moved to alloc_and_link_pwqs() as that now is the only place which is explicitly handling the two pwq types. This patch doesn't introduce any visible behavior changes. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r--kernel/workqueue.c53
1 files changed, 22 insertions, 31 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 8634fc9d52d2..2db1532b09dc 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -273,12 +273,6 @@ static inline int __next_wq_cpu(int cpu, const struct cpumask *mask,
273 return WORK_CPU_END; 273 return WORK_CPU_END;
274} 274}
275 275
276static inline int __next_pwq_cpu(int cpu, const struct cpumask *mask,
277 struct workqueue_struct *wq)
278{
279 return __next_wq_cpu(cpu, mask, !(wq->flags & WQ_UNBOUND) ? 1 : 2);
280}
281
282/* 276/*
283 * CPU iterators 277 * CPU iterators
284 * 278 *
@@ -289,8 +283,6 @@ static inline int __next_pwq_cpu(int cpu, const struct cpumask *mask,
289 * 283 *
290 * for_each_wq_cpu() : possible CPUs + WORK_CPU_UNBOUND 284 * for_each_wq_cpu() : possible CPUs + WORK_CPU_UNBOUND
291 * for_each_online_wq_cpu() : online CPUs + WORK_CPU_UNBOUND 285 * for_each_online_wq_cpu() : online CPUs + WORK_CPU_UNBOUND
292 * for_each_pwq_cpu() : possible CPUs for bound workqueues,
293 * WORK_CPU_UNBOUND for unbound workqueues
294 */ 286 */
295#define for_each_wq_cpu(cpu) \ 287#define for_each_wq_cpu(cpu) \
296 for ((cpu) = __next_wq_cpu(-1, cpu_possible_mask, 3); \ 288 for ((cpu) = __next_wq_cpu(-1, cpu_possible_mask, 3); \
@@ -302,10 +294,13 @@ static inline int __next_pwq_cpu(int cpu, const struct cpumask *mask,
302 (cpu) < WORK_CPU_END; \ 294 (cpu) < WORK_CPU_END; \
303 (cpu) = __next_wq_cpu((cpu), cpu_online_mask, 3)) 295 (cpu) = __next_wq_cpu((cpu), cpu_online_mask, 3))
304 296
305#define for_each_pwq_cpu(cpu, wq) \ 297/**
306 for ((cpu) = __next_pwq_cpu(-1, cpu_possible_mask, (wq)); \ 298 * for_each_pwq - iterate through all pool_workqueues of the specified workqueue
307 (cpu) < WORK_CPU_END; \ 299 * @pwq: iteration cursor
308 (cpu) = __next_pwq_cpu((cpu), cpu_possible_mask, (wq))) 300 * @wq: the target workqueue
301 */
302#define for_each_pwq(pwq, wq) \
303 list_for_each_entry((pwq), &(wq)->pwqs, pwqs_node)
309 304
310#ifdef CONFIG_DEBUG_OBJECTS_WORK 305#ifdef CONFIG_DEBUG_OBJECTS_WORK
311 306
@@ -2505,15 +2500,14 @@ static bool flush_workqueue_prep_pwqs(struct workqueue_struct *wq,
2505 int flush_color, int work_color) 2500 int flush_color, int work_color)
2506{ 2501{
2507 bool wait = false; 2502 bool wait = false;
2508 unsigned int cpu; 2503 struct pool_workqueue *pwq;
2509 2504
2510 if (flush_color >= 0) { 2505 if (flush_color >= 0) {
2511 WARN_ON_ONCE(atomic_read(&wq->nr_pwqs_to_flush)); 2506 WARN_ON_ONCE(atomic_read(&wq->nr_pwqs_to_flush));
2512 atomic_set(&wq->nr_pwqs_to_flush, 1); 2507 atomic_set(&wq->nr_pwqs_to_flush, 1);
2513 } 2508 }
2514 2509
2515 for_each_pwq_cpu(cpu, wq) { 2510 for_each_pwq(pwq, wq) {
2516 struct pool_workqueue *pwq = get_pwq(cpu, wq);
2517 struct worker_pool *pool = pwq->pool; 2511 struct worker_pool *pool = pwq->pool;
2518 2512
2519 spin_lock_irq(&pool->lock); 2513 spin_lock_irq(&pool->lock);
@@ -2712,7 +2706,7 @@ EXPORT_SYMBOL_GPL(flush_workqueue);
2712void drain_workqueue(struct workqueue_struct *wq) 2706void drain_workqueue(struct workqueue_struct *wq)
2713{ 2707{
2714 unsigned int flush_cnt = 0; 2708 unsigned int flush_cnt = 0;
2715 unsigned int cpu; 2709 struct pool_workqueue *pwq;
2716 2710
2717 /* 2711 /*
2718 * __queue_work() needs to test whether there are drainers, is much 2712 * __queue_work() needs to test whether there are drainers, is much
@@ -2726,8 +2720,7 @@ void drain_workqueue(struct workqueue_struct *wq)
2726reflush: 2720reflush:
2727 flush_workqueue(wq); 2721 flush_workqueue(wq);
2728 2722
2729 for_each_pwq_cpu(cpu, wq) { 2723 for_each_pwq(pwq, wq) {
2730 struct pool_workqueue *pwq = get_pwq(cpu, wq);
2731 bool drained; 2724 bool drained;
2732 2725
2733 spin_lock_irq(&pwq->pool->lock); 2726 spin_lock_irq(&pwq->pool->lock);
@@ -3100,6 +3093,7 @@ int keventd_up(void)
3100 3093
3101static int alloc_and_link_pwqs(struct workqueue_struct *wq) 3094static int alloc_and_link_pwqs(struct workqueue_struct *wq)
3102{ 3095{
3096 bool highpri = wq->flags & WQ_HIGHPRI;
3103 int cpu; 3097 int cpu;
3104 3098
3105 if (!(wq->flags & WQ_UNBOUND)) { 3099 if (!(wq->flags & WQ_UNBOUND)) {
@@ -3110,6 +3104,7 @@ static int alloc_and_link_pwqs(struct workqueue_struct *wq)
3110 for_each_possible_cpu(cpu) { 3104 for_each_possible_cpu(cpu) {
3111 struct pool_workqueue *pwq = get_pwq(cpu, wq); 3105 struct pool_workqueue *pwq = get_pwq(cpu, wq);
3112 3106
3107 pwq->pool = get_std_worker_pool(cpu, highpri);
3113 list_add_tail(&pwq->pwqs_node, &wq->pwqs); 3108 list_add_tail(&pwq->pwqs_node, &wq->pwqs);
3114 } 3109 }
3115 } else { 3110 } else {
@@ -3120,6 +3115,7 @@ static int alloc_and_link_pwqs(struct workqueue_struct *wq)
3120 return -ENOMEM; 3115 return -ENOMEM;
3121 3116
3122 wq->pool_wq.single = pwq; 3117 wq->pool_wq.single = pwq;
3118 pwq->pool = get_std_worker_pool(WORK_CPU_UNBOUND, highpri);
3123 list_add_tail(&pwq->pwqs_node, &wq->pwqs); 3119 list_add_tail(&pwq->pwqs_node, &wq->pwqs);
3124 } 3120 }
3125 3121
@@ -3154,7 +3150,7 @@ struct workqueue_struct *__alloc_workqueue_key(const char *fmt,
3154{ 3150{
3155 va_list args, args1; 3151 va_list args, args1;
3156 struct workqueue_struct *wq; 3152 struct workqueue_struct *wq;
3157 unsigned int cpu; 3153 struct pool_workqueue *pwq;
3158 size_t namelen; 3154 size_t namelen;
3159 3155
3160 /* determine namelen, allocate wq and format name */ 3156 /* determine namelen, allocate wq and format name */
@@ -3195,11 +3191,8 @@ struct workqueue_struct *__alloc_workqueue_key(const char *fmt,
3195 if (alloc_and_link_pwqs(wq) < 0) 3191 if (alloc_and_link_pwqs(wq) < 0)
3196 goto err; 3192 goto err;
3197 3193
3198 for_each_pwq_cpu(cpu, wq) { 3194 for_each_pwq(pwq, wq) {
3199 struct pool_workqueue *pwq = get_pwq(cpu, wq);
3200
3201 BUG_ON((unsigned long)pwq & WORK_STRUCT_FLAG_MASK); 3195 BUG_ON((unsigned long)pwq & WORK_STRUCT_FLAG_MASK);
3202 pwq->pool = get_std_worker_pool(cpu, flags & WQ_HIGHPRI);
3203 pwq->wq = wq; 3196 pwq->wq = wq;
3204 pwq->flush_color = -1; 3197 pwq->flush_color = -1;
3205 pwq->max_active = max_active; 3198 pwq->max_active = max_active;
@@ -3234,8 +3227,8 @@ struct workqueue_struct *__alloc_workqueue_key(const char *fmt,
3234 spin_lock_irq(&workqueue_lock); 3227 spin_lock_irq(&workqueue_lock);
3235 3228
3236 if (workqueue_freezing && wq->flags & WQ_FREEZABLE) 3229 if (workqueue_freezing && wq->flags & WQ_FREEZABLE)
3237 for_each_pwq_cpu(cpu, wq) 3230 for_each_pwq(pwq, wq)
3238 get_pwq(cpu, wq)->max_active = 0; 3231 pwq->max_active = 0;
3239 3232
3240 list_add(&wq->list, &workqueues); 3233 list_add(&wq->list, &workqueues);
3241 3234
@@ -3261,14 +3254,13 @@ EXPORT_SYMBOL_GPL(__alloc_workqueue_key);
3261 */ 3254 */
3262void destroy_workqueue(struct workqueue_struct *wq) 3255void destroy_workqueue(struct workqueue_struct *wq)
3263{ 3256{
3264 unsigned int cpu; 3257 struct pool_workqueue *pwq;
3265 3258
3266 /* drain it before proceeding with destruction */ 3259 /* drain it before proceeding with destruction */
3267 drain_workqueue(wq); 3260 drain_workqueue(wq);
3268 3261
3269 /* sanity checks */ 3262 /* sanity checks */
3270 for_each_pwq_cpu(cpu, wq) { 3263 for_each_pwq(pwq, wq) {
3271 struct pool_workqueue *pwq = get_pwq(cpu, wq);
3272 int i; 3264 int i;
3273 3265
3274 for (i = 0; i < WORK_NR_COLORS; i++) 3266 for (i = 0; i < WORK_NR_COLORS; i++)
@@ -3330,7 +3322,7 @@ static void pwq_set_max_active(struct pool_workqueue *pwq, int max_active)
3330 */ 3322 */
3331void workqueue_set_max_active(struct workqueue_struct *wq, int max_active) 3323void workqueue_set_max_active(struct workqueue_struct *wq, int max_active)
3332{ 3324{
3333 unsigned int cpu; 3325 struct pool_workqueue *pwq;
3334 3326
3335 max_active = wq_clamp_max_active(max_active, wq->flags, wq->name); 3327 max_active = wq_clamp_max_active(max_active, wq->flags, wq->name);
3336 3328
@@ -3338,8 +3330,7 @@ void workqueue_set_max_active(struct workqueue_struct *wq, int max_active)
3338 3330
3339 wq->saved_max_active = max_active; 3331 wq->saved_max_active = max_active;
3340 3332
3341 for_each_pwq_cpu(cpu, wq) { 3333 for_each_pwq(pwq, wq) {
3342 struct pool_workqueue *pwq = get_pwq(cpu, wq);
3343 struct worker_pool *pool = pwq->pool; 3334 struct worker_pool *pool = pwq->pool;
3344 3335
3345 spin_lock(&pool->lock); 3336 spin_lock(&pool->lock);