History

workqueue: protect wq->saved_max_active with wq->mutex

We're expanding wq->mutex to cover all fields specific to each workqueue with the end goal of replacing pwq_lock which will make locking simpler and easier to understand. This patch makes wq->saved_max_active protected by wq->mutex instead of pwq_lock. As pwq_lock locking around pwq_adjust_mac_active() is no longer necessary, this patch also replaces pwq_lock lockings of for_each_pwq() around pwq_adjust_max_active() to wq->mutex. tj: Rebased on top of the current dev branch. Updated description.

Lai Jiangshan committed 13 years ago

Commit a357fc01 parent b09f4fd1 file · +16 −17Browse files

Showing the changes to kernel/workqueue.c (1 of 1 file). Show all

Unified · Split

kernel/workqueue.c+16−17
@@ -243,7 +243,7 @@ struct workqueue_struct { · 242 unmodified lines
243243 struct worker *rescuer; /* I: rescue worker */
244244
245245 int nr_drainers; /* WQ: drain in progress */
246− int saved_max_active; /* PW: saved pwq max_active */
246+ int saved_max_active; /* WQ: saved pwq max_active */
247247
248248 #ifdef CONFIG_SYSFS
249249 struct wq_device *wq_dev; /* I: for sysfs interface */
@@ -3579,13 +3579,13 @@ static void pwq_adjust_max_active(struct pool_workqueue *pwq) · 3329 unmodified lines
35793579 bool freezable = wq->flags & WQ_FREEZABLE;
35803580
35813581 /* for @wq->saved_max_active */
3582− lockdep_assert_held(&pwq_lock);
3582+ lockdep_assert_held(&wq->mutex);
35833583
35843584 /* fast exit for non-freezable wqs */
35853585 if (!freezable && pwq->max_active == wq->saved_max_active)
35863586 return;
35873587
3588− spin_lock(&pwq->pool->lock);
3588+ spin_lock_irq(&pwq->pool->lock);
35893589
35903590 if (!freezable || !(pwq->pool->flags & POOL_FREEZING)) {
35913591 pwq->max_active = wq->saved_max_active;
@@ -3603,7 +3603,7 @@ static void pwq_adjust_max_active(struct pool_workqueue *pwq) · 11 unmodified lines
36033603 pwq->max_active = 0;
36043604 }
36053605
3606− spin_unlock(&pwq->pool->lock);
3606+ spin_unlock_irq(&pwq->pool->lock);
36073607 }
36083608
36093609 static void init_and_link_pwq(struct pool_workqueue *pwq,
@@ -3622,7 +3622,6 @@ static void init_and_link_pwq(struct pool_workqueue *pwq, · 12 unmodified lines
36223622 INIT_WORK(&pwq->unbound_release_work, pwq_unbound_release_workfn);
36233623
36243624 mutex_lock(&wq->mutex);
3625− spin_lock_irq(&pwq_lock);
36263625
36273626 /*
36283627 * Set the matching work_color. This is synchronized with
@@ -3636,9 +3635,10 @@ static void init_and_link_pwq(struct pool_workqueue *pwq, · 7 unmodified lines
36363635 pwq_adjust_max_active(pwq);
36373636
36383637 /* link in @pwq */
3638+ spin_lock_irq(&pwq_lock);
36393639 list_add_rcu(&pwq->pwqs_node, &wq->pwqs);
3640−
36413640 spin_unlock_irq(&pwq_lock);
3641+
36423642 mutex_unlock(&wq->mutex);
36433643 }
36443644
@@ -3803,10 +3803,10 @@ struct workqueue_struct *__alloc_workqueue_key(const char *fmt, · 158 unmodified lines
38033803 */
38043804 mutex_lock(&wq_pool_mutex);
38053805
3806− spin_lock_irq(&pwq_lock);
3806+ mutex_lock(&wq->mutex);
38073807 for_each_pwq(pwq, wq)
38083808 pwq_adjust_max_active(pwq);
3809− spin_unlock_irq(&pwq_lock);
3809+ mutex_unlock(&wq->mutex);
38103810
38113811 list_add(&wq->list, &workqueues);
38123812
@@ -3917,14 +3917,14 @@ void workqueue_set_max_active(struct workqueue_struct *wq, int max_active) · 104 unmodified lines
39173917
39183918 max_active = wq_clamp_max_active(max_active, wq->flags, wq->name);
39193919
3920− spin_lock_irq(&pwq_lock);
3920+ mutex_lock(&wq->mutex);
39213921
39223922 wq->saved_max_active = max_active;
39233923
39243924 for_each_pwq(pwq, wq)
39253925 pwq_adjust_max_active(pwq);
39263926
3927− spin_unlock_irq(&pwq_lock);
3927+ mutex_unlock(&wq->mutex);
39283928 }
39293929 EXPORT_SYMBOL_GPL(workqueue_set_max_active);
39303930
@@ -4287,7 +4287,7 @@ EXPORT_SYMBOL_GPL(work_on_cpu); · 356 unmodified lines
42874287 * pool->worklist.
42884288 *
42894289 * CONTEXT:
4290− * Grabs and releases wq_pool_mutex, pwq_lock and pool->lock's.
4290+ * Grabs and releases wq_pool_mutex, wq->mutex and pool->lock's.
42914291 */
42924292 void freeze_workqueues_begin(void)
42934293 {
@@ -4309,13 +4309,12 @@ void freeze_workqueues_begin(void) · 15 unmodified lines
43094309 spin_unlock_irq(&pool->lock);
43104310 }
43114311
4312− /* suppress further executions by setting max_active to zero */
4313− spin_lock_irq(&pwq_lock);
43144312 list_for_each_entry(wq, &workqueues, list) {
4313+ mutex_lock(&wq->mutex);
43154314 for_each_pwq(pwq, wq)
43164315 pwq_adjust_max_active(pwq);
4316+ mutex_unlock(&wq->mutex);
43174317 }
4318− spin_unlock_irq(&pwq_lock);
43194318
43204319 mutex_unlock(&wq_pool_mutex);
43214320 }
@@ -4373,7 +4372,7 @@ out_unlock: · 51 unmodified lines
43734372 * frozen works are transferred to their respective pool worklists.
43744373 *
43754374 * CONTEXT:
4376− * Grabs and releases wq_pool_mutex, pwq_lock and pool->lock's.
4375+ * Grabs and releases wq_pool_mutex, wq->mutex and pool->lock's.
43774376 */
43784377 void thaw_workqueues(void)
43794378 {
@@ -4396,12 +4395,12 @@ void thaw_workqueues(void) · 16 unmodified lines
43964395 }
43974396
43984397 /* restore max_active and repopulate worklist */
4399− spin_lock_irq(&pwq_lock);
44004398 list_for_each_entry(wq, &workqueues, list) {
4399+ mutex_lock(&wq->mutex);
44014400 for_each_pwq(pwq, wq)
44024401 pwq_adjust_max_active(pwq);
4402+ mutex_unlock(&wq->mutex);
44034403 }
4404− spin_unlock_irq(&pwq_lock);
44054404
44064405 workqueue_freezing = false;
44074406 out_unlock:

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t