diff options
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r-- | kernel/workqueue.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 2c2f971f3e75..23231237f2e2 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -3647,8 +3647,12 @@ static int apply_workqueue_attrs_locked(struct workqueue_struct *wq, | |||
3647 | return -EINVAL; | 3647 | return -EINVAL; |
3648 | 3648 | ||
3649 | /* creating multiple pwqs breaks ordering guarantee */ | 3649 | /* creating multiple pwqs breaks ordering guarantee */ |
3650 | if (WARN_ON((wq->flags & __WQ_ORDERED) && !list_empty(&wq->pwqs))) | 3650 | if (!list_empty(&wq->pwqs)) { |
3651 | return -EINVAL; | 3651 | if (WARN_ON(wq->flags & __WQ_ORDERED_EXPLICIT)) |
3652 | return -EINVAL; | ||
3653 | |||
3654 | wq->flags &= ~__WQ_ORDERED; | ||
3655 | } | ||
3652 | 3656 | ||
3653 | ctx = apply_wqattrs_prepare(wq, attrs); | 3657 | ctx = apply_wqattrs_prepare(wq, attrs); |
3654 | 3658 | ||
@@ -3834,6 +3838,16 @@ struct workqueue_struct *__alloc_workqueue_key(const char *fmt, | |||
3834 | struct workqueue_struct *wq; | 3838 | struct workqueue_struct *wq; |
3835 | struct pool_workqueue *pwq; | 3839 | struct pool_workqueue *pwq; |
3836 | 3840 | ||
3841 | /* | ||
3842 | * Unbound && max_active == 1 used to imply ordered, which is no | ||
3843 | * longer the case on NUMA machines due to per-node pools. While | ||
3844 | * alloc_ordered_workqueue() is the right way to create an ordered | ||
3845 | * workqueue, keep the previous behavior to avoid subtle breakages | ||
3846 | * on NUMA. | ||
3847 | */ | ||
3848 | if ((flags & WQ_UNBOUND) && max_active == 1) | ||
3849 | flags |= __WQ_ORDERED; | ||
3850 | |||
3837 | /* see the comment above the definition of WQ_POWER_EFFICIENT */ | 3851 | /* see the comment above the definition of WQ_POWER_EFFICIENT */ |
3838 | if ((flags & WQ_POWER_EFFICIENT) && wq_power_efficient) | 3852 | if ((flags & WQ_POWER_EFFICIENT) && wq_power_efficient) |
3839 | flags |= WQ_UNBOUND; | 3853 | flags |= WQ_UNBOUND; |
@@ -4022,13 +4036,14 @@ void workqueue_set_max_active(struct workqueue_struct *wq, int max_active) | |||
4022 | struct pool_workqueue *pwq; | 4036 | struct pool_workqueue *pwq; |
4023 | 4037 | ||
4024 | /* disallow meddling with max_active for ordered workqueues */ | 4038 | /* disallow meddling with max_active for ordered workqueues */ |
4025 | if (WARN_ON(wq->flags & __WQ_ORDERED)) | 4039 | if (WARN_ON(wq->flags & __WQ_ORDERED_EXPLICIT)) |
4026 | return; | 4040 | return; |
4027 | 4041 | ||
4028 | max_active = wq_clamp_max_active(max_active, wq->flags, wq->name); | 4042 | max_active = wq_clamp_max_active(max_active, wq->flags, wq->name); |
4029 | 4043 | ||
4030 | mutex_lock(&wq->mutex); | 4044 | mutex_lock(&wq->mutex); |
4031 | 4045 | ||
4046 | wq->flags &= ~__WQ_ORDERED; | ||
4032 | wq->saved_max_active = max_active; | 4047 | wq->saved_max_active = max_active; |
4033 | 4048 | ||
4034 | for_each_pwq(pwq, wq) | 4049 | for_each_pwq(pwq, wq) |
@@ -5154,7 +5169,7 @@ int workqueue_sysfs_register(struct workqueue_struct *wq) | |||
5154 | * attributes breaks ordering guarantee. Disallow exposing ordered | 5169 | * attributes breaks ordering guarantee. Disallow exposing ordered |
5155 | * workqueues. | 5170 | * workqueues. |
5156 | */ | 5171 | */ |
5157 | if (WARN_ON(wq->flags & __WQ_ORDERED)) | 5172 | if (WARN_ON(wq->flags & __WQ_ORDERED_EXPLICIT)) |
5158 | return -EINVAL; | 5173 | return -EINVAL; |
5159 | 5174 | ||
5160 | wq->wq_dev = wq_dev = kzalloc(sizeof(*wq_dev), GFP_KERNEL); | 5175 | wq->wq_dev = wq_dev = kzalloc(sizeof(*wq_dev), GFP_KERNEL); |