Skip to content

Commit 84193c0

Browse files
committed
workqueue: Generalize unbound CPU pods
While renamed to pod, the code still assumes that the pods are defined by NUMA boundaries. Let's generalize it: * workqueue_attrs->affn_scope is added. Each enum represents the type of boundaries that define the pods. There are currently two scopes - WQ_AFFN_NUMA and WQ_AFFN_SYSTEM. The former is the same behavior as before - one pod per NUMA node. The latter defines one global pod across the whole system. * struct wq_pod_type is added which describes how pods are configured for each affnity scope. For each pod, it lists the member CPUs and the preferred NUMA node for memory allocations. The reverse mapping from CPU to pod is also available. * wq_pod_enabled is dropped. Pod is now always enabled. The previously disabled behavior is now implemented through WQ_AFFN_SYSTEM. * get_unbound_pool() wants to determine the NUMA node to allocate memory from for the new pool. The variables are renamed from node to pod but the logic still assumes they're one and the same. Clearly distinguish them - walk the WQ_AFFN_NUMA pods to find the matching pod and then use the pod's NUMA node. * wq_calc_pod_cpumask() was taking @pod but assumed that it was the NUMA node. Take @cpu instead and determine the cpumask to use from the pod_type matching @attrs. * apply_wqattrs_prepare() is update to return ERR_PTR() on error instead of NULL so that it can indicate -EINVAL on invalid affinity scopes. This patch allows CPUs to be grouped into pods however desired per type. While this patch causes some internal behavior changes, nothing material should change for workqueue users. v2: Trigger WARN_ON_ONCE() in wqattrs_pod_type() if affn_scope is WQ_AFFN_NR_TYPES which indicates that the function is called with a worker_pool's attrs instead of a workqueue's. Signed-off-by: Tejun Heo <[email protected]>
1 parent 5de7a03 commit 84193c0

File tree

2 files changed

+137
-65
lines changed

2 files changed

+137
-65
lines changed

include/linux/workqueue.h

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,15 @@ struct rcu_work {
125125
struct workqueue_struct *wq;
126126
};
127127

128+
enum wq_affn_scope {
129+
WQ_AFFN_NUMA, /* one pod per NUMA node */
130+
WQ_AFFN_SYSTEM, /* one pod across the whole system */
131+
132+
WQ_AFFN_NR_TYPES,
133+
134+
WQ_AFFN_DFL = WQ_AFFN_NUMA,
135+
};
136+
128137
/**
129138
* struct workqueue_attrs - A struct for workqueue attributes.
130139
*
@@ -141,12 +150,26 @@ struct workqueue_attrs {
141150
*/
142151
cpumask_var_t cpumask;
143152

153+
/*
154+
* Below fields aren't properties of a worker_pool. They only modify how
155+
* :c:func:`apply_workqueue_attrs` select pools and thus don't
156+
* participate in pool hash calculations or equality comparisons.
157+
*/
158+
144159
/**
145-
* @ordered: work items must be executed one by one in queueing order
160+
* @affn_scope: unbound CPU affinity scope
146161
*
147-
* Unlike other fields, ``ordered`` isn't a property of a worker_pool. It
148-
* only modifies how :c:func:`apply_workqueue_attrs` select pools and thus
149-
* doesn't participate in pool hash calculations or equality comparisons.
162+
* CPU pods are used to improve execution locality of unbound work
163+
* items. There are multiple pod types, one for each wq_affn_scope, and
164+
* every CPU in the system belongs to one pod in every pod type. CPUs
165+
* that belong to the same pod share the worker pool. For example,
166+
* selecting %WQ_AFFN_NUMA makes the workqueue use a separate worker
167+
* pool for each NUMA node.
168+
*/
169+
enum wq_affn_scope affn_scope;
170+
171+
/**
172+
* @ordered: work items must be executed one by one in queueing order
150173
*/
151174
bool ordered;
152175
};

0 commit comments

Comments
 (0)