Factor out lock pool, put_pwq(), unlock sequence into put_pwq_unlocked(). The two existing places are converted and there will be more with NUMA affinity support. This is to prepare for NUMA affinity support for unbound workqueues and doesn't introduce any functional difference.
Showing the changes to kernel/workqueue.c (1 of 1 file). Show all
Unified · Split
| @@ -1057,6 +1057,25 @@ static void put_pwq(struct pool_workqueue *pwq) · 1056 unmodified lines | ||
| 1057 | 1057 | schedule_work(&pwq->unbound_release_work); |
| 1058 | 1058 | } |
| 1059 | 1059 | |
| 1060 | +/** | |
| 1061 | + * put_pwq_unlocked - put_pwq() with surrounding pool lock/unlock | |
| 1062 | + * @pwq: pool_workqueue to put (can be %NULL) | |
| 1063 | + * | |
| 1064 | + * put_pwq() with locking. This function also allows %NULL @pwq. | |
| 1065 | + */ | |
| 1066 | +static void put_pwq_unlocked(struct pool_workqueue *pwq) | |
| 1067 | +{ | |
| 1068 | + if (pwq) { | |
| 1069 | + /* | |
| 1070 | + * As both pwqs and pools are sched-RCU protected, the | |
| 1071 | + * following lock operations are safe. | |
| 1072 | + */ | |
| 1073 | + spin_lock_irq(&pwq->pool->lock); | |
| 1074 | + put_pwq(pwq); | |
| 1075 | + spin_unlock_irq(&pwq->pool->lock); | |
| 1076 | + } | |
| 1077 | +} | |
| 1078 | + | |
| 1060 | 1079 | static void pwq_activate_delayed_work(struct work_struct *work) |
| 1061 | 1080 | { |
| 1062 | 1081 | struct pool_workqueue *pwq = get_work_pwq(work); |
| @@ -3759,12 +3778,7 @@ int apply_workqueue_attrs(struct workqueue_struct *wq, · 2696 unmodified lines | ||
| 3759 | 3778 | |
| 3760 | 3779 | mutex_unlock(&wq->mutex); |
| 3761 | 3780 | |
| 3762 | − if (last_pwq) { | |
| 3763 | − spin_lock_irq(&last_pwq->pool->lock); | |
| 3764 | − put_pwq(last_pwq); | |
| 3765 | − spin_unlock_irq(&last_pwq->pool->lock); | |
| 3766 | − } | |
| 3767 | − | |
| 3781 | + put_pwq_unlocked(last_pwq); | |
| 3768 | 3782 | ret = 0; |
| 3769 | 3783 | /* fall through */ |
| 3770 | 3784 | out_free: |
| @@ -3979,16 +3993,12 @@ void destroy_workqueue(struct workqueue_struct *wq) · 208 unmodified lines | ||
| 3979 | 3993 | } else { |
| 3980 | 3994 | /* |
| 3981 | 3995 | * We're the sole accessor of @wq at this point. Directly |
| 3982 | − * access the first pwq and put the base ref. As both pwqs | |
| 3983 | − * and pools are sched-RCU protected, the lock operations | |
| 3984 | − * are safe. @wq will be freed when the last pwq is | |
| 3985 | − * released. | |
| 3996 | + * access the first pwq and put the base ref. @wq will be | |
| 3997 | + * freed when the last pwq is released. | |
| 3986 | 3998 | */ |
| 3987 | 3999 | pwq = list_first_entry(&wq->pwqs, struct pool_workqueue, |
| 3988 | 4000 | pwqs_node); |
| 3989 | − spin_lock_irq(&pwq->pool->lock); | |
| 3990 | − put_pwq(pwq); | |
| 3991 | − spin_unlock_irq(&pwq->pool->lock); | |
| 4001 | + put_pwq_unlocked(pwq); | |
| 3992 | 4002 | } |
| 3993 | 4003 | } |
| 3994 | 4004 | EXPORT_SYMBOL_GPL(destroy_workqueue); |