Patch "workqueue: implicit ordered attribute should be overridable" has been added to the 4.9-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
workqueue: implicit ordered attribute should be overridable
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
workqueue-implicit-ordered-attribute-should-be-overridable.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
0a94efb5acbb6980d7c9ab604372d93cd507e4d8Mon Sep 17 00:00:00 2001
From: Tejun Heo <[email protected]>
Date: Sun, 23 Jul 2017 08:36:15 -0400
Subject: workqueue: implicit ordered attribute should be overridable
From: Tejun Heo <[email protected]>
commit 0a94efb5acbb6980d7c9ab604372d93cd507e4d8 upstream.
5c0338c68706 ("workqueue: restore WQ_UNBOUND/max_active==1 to be ordered") automatically enabled ordered attribute for unbound workqueues w/ max_active == 1. Because ordered workqueues reject max_active and some attribute changes, this implicit ordered mode broke cases where the user creates an unbound workqueue w/ max_active == 1 and later explicitly changes the related attributes.
This patch distinguishes explicit and implicit ordered setting and overrides from attribute changes if implict.
--- include/linux/workqueue.h | 4 +++- kernel/workqueue.c | 13 +++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-)
include/linux/workqueue.h +3 -1
@@ -311,6 +311,7 @@ enum { __WQ_DRAINING =1 <<16 ,/* internal: workqueue is draining */ __WQ_ORDERED =1 <<17 ,/* internal: workqueue is ordered */ + __WQ_ORDERED_EXPLICIT =1 <<18 ,/* internal: alloc_ordered_workqueue() */ __WQ_LEGACY =1 <<18 ,/* internal: create*_workqueue() */ WQ_MAX_ACTIVE = 512, /* I like 512, better ideas? */
@@ -409,7 +410,8 @@ __alloc_workqueue_key(const char *fmt, u* Pointer to the allocated workqueue on success, %NULL on failure. */ #define alloc_ordered_workqueue(fmt, flags, args...) \ - alloc_workqueue(fmt, WQ_UNBOUND | __WQ_ORDERED | (flags), 1, ##args) + alloc_workqueue(fmt, WQ_UNBOUND | __WQ_ORDERED | \ + __WQ_ORDERED_EXPLICIT | (flags), 1, ##args)#define create_workqueue (name) \ alloc_workqueue("%s", __WQ_LEGACY | WQ_MEM_RECLAIM, 1, (name))
kernel/workqueue.c +9 -4
@@ -3730,8 +3730,12 @@ static int apply_workqueue_attrs_locked(return -EINVAL ;/* creating multiple pwqs breaks ordering guarantee */ -if (WARN_ON ((wq->flags & __WQ_ORDERED) && !list_empty (&wq->pwqs))) -return -EINVAL ; +if (!list_empty (&wq->pwqs)) { +if (WARN_ON (wq->flags & __WQ_ORDERED_EXPLICIT)) +return -EINVAL ; + + wq->flags &= ~__WQ_ORDERED; + } ctx =apply_wqattrs_prepare (wq, attrs);if (!ctx)
@@ -4113,13 +4117,14 @@ void workqueue_set_max_active(struct worstruct pool_workqueue *pwq;/* disallow meddling with max_active for ordered workqueues */ -if (WARN_ON (wq->flags & __WQ_ORDERED)) +if (WARN_ON (wq->flags & __WQ_ORDERED_EXPLICIT))return ; max_active =wq_clamp_max_active (max_active, wq->flags, wq->name);mutex_lock (&wq->mutex); + wq->flags &= ~__WQ_ORDERED; wq->saved_max_active = max_active;for_each_pwq (pwq, wq)
@@ -5224,7 +5229,7 @@ int workqueue_sysfs_register(struct work* attributes breaks ordering guarantee. Disallow exposing ordered * workqueues. */ -if (WARN_ON (wq->flags & __WQ_ORDERED)) +if (WARN_ON (wq->flags & __WQ_ORDERED_EXPLICIT))return -EINVAL ; wq->wq_dev = wq_dev =kzalloc (sizeof (*wq_dev),GFP_KERNEL );
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/cgroup-create-dfl_root-files-on-subsys-registration.patch queue-4.9/cgroup-fix-error-return-value-from-cgroup_subtree_control.patch queue-4.9/workqueue-implicit-ordered-attribute-should-be-overridable.patch queue-4.9/workqueue-restore-wq_unbound-max_active-1-to-be-ordered.patch queue-4.9/libata-array-underflow-in-ata_find_dev.patch