aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2017-07-24 13:14:46 +1000
committerStephen Rothwell <sfr@canb.auug.org.au>2017-07-24 13:14:46 +1000
commite2779ba33719a2d119be50afe40cc4e854a2a5f9 (patch)
tree210d8881d4e4aee5c036fb133ba7c544506445a8
parentb21a87c5b7539d9647f26085df3d3380f599643a (diff)
parentd593b7e8b15f6b2f755371584a8eb6ad545784ef (diff)
Merge remote-tracking branch 'workqueues/for-next'
-rw-r--r--Documentation/core-api/workqueue.rst10
-rw-r--r--kernel/workqueue.c10
2 files changed, 17 insertions, 3 deletions
diff --git a/Documentation/core-api/workqueue.rst b/Documentation/core-api/workqueue.rst
index ffdec94fbca1..3943b5bfa8cf 100644
--- a/Documentation/core-api/workqueue.rst
+++ b/Documentation/core-api/workqueue.rst
@@ -243,11 +243,15 @@ throttling the number of active work items, specifying '0' is
recommended.
Some users depend on the strict execution ordering of ST wq. The
-combination of ``@max_active`` of 1 and ``WQ_UNBOUND`` is used to
-achieve this behavior. Work items on such wq are always queued to the
-unbound worker-pools and only one work item can be active at any given
+combination of ``@max_active`` of 1 and ``WQ_UNBOUND`` used to
+achieve this behavior. Work items on such wq were always queued to the
+unbound worker-pools and only one work item could be active at any given
time thus achieving the same ordering property as ST wq.
+In the current implementation the above configuration only guarantees
+ST behavior within a given NUMA node. Instead alloc_ordered_queue should
+be used to achieve system wide ST behavior.
+
Example Execution Scenarios
===========================
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index a86688fabc55..abe4a4971c24 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -3929,6 +3929,16 @@ struct workqueue_struct *__alloc_workqueue_key(const char *fmt,
struct workqueue_struct *wq;
struct pool_workqueue *pwq;
+ /*
+ * Unbound && max_active == 1 used to imply ordered, which is no
+ * longer the case on NUMA machines due to per-node pools. While
+ * alloc_ordered_workqueue() is the right way to create an ordered
+ * workqueue, keep the previous behavior to avoid subtle breakages
+ * on NUMA.
+ */
+ if ((flags & WQ_UNBOUND) && max_active == 1)
+ flags |= __WQ_ORDERED;
+
/* see the comment above the definition of WQ_POWER_EFFICIENT */
if ((flags & WQ_POWER_EFFICIENT) && wq_power_efficient)
flags |= WQ_UNBOUND;