summaryrefslogtreecommitdiff
path: root/kernel/workqueue.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2026-09-01 11:09:27 -1000
committerTejun Heo <tj@kernel.org>2026-09-08 07:31:11 -1000
commit84a42d3829f0088967411106b81e942a67d0b53c (patch)
tree79ca55d3a06d7f88dad5a319f86efd80c3224e60 /kernel/workqueue.c
parent1298c43b673274920b26e77d3df55c18c3b82f90 (diff)
downloadlinux-next-84a42d3829f0088967411106b81e942a67d0b53c.tar.gz
linux-next-84a42d3829f0088967411106b81e942a67d0b53c.zip
workqueue: Add for_each_node_with_fallback()
Per-node arrays in workqueue carry an extra slot at nr_node_ids for NUMA_NO_NODE, and iterating them open-codes for_each_node() plus separate handling of that slot. Add for_each_node_with_fallback() and convert alloc/free_node_nr_active(). Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r--kernel/workqueue.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 79bb8482bc8d..298f22c4caad 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -623,6 +623,26 @@ static void show_one_worker_pool(struct worker_pool *pool);
list_for_each_entry_rcu((pwq), &(wq)->pwqs, pwqs_node, \
lockdep_is_held(&(wq->mutex)))
+/*
+ * Per-node arrays in this file carry an extra slot at nr_node_ids serving
+ * NUMA_NO_NODE. Return the slot after all nodes.
+ */
+static int next_node_with_fallback(int node)
+{
+ if (node >= nr_node_ids)
+ return nr_node_ids + 1;
+
+ node = next_node(node, node_possible_map);
+ if (node >= nr_node_ids)
+ return nr_node_ids;
+ return node;
+}
+
+#define for_each_node_with_fallback(node) \
+ for ((node) = first_node(node_possible_map); \
+ (node) <= nr_node_ids; \
+ (node) = next_node_with_fallback(node))
+
#ifdef CONFIG_DEBUG_OBJECTS_WORK
static const struct debug_obj_descr work_debug_descr;
@@ -5083,13 +5103,10 @@ static void free_node_nr_active(struct wq_node_nr_active **nna_ar)
{
int node;
- for_each_node(node) {
+ for_each_node_with_fallback(node) {
kfree(nna_ar[node]);
nna_ar[node] = NULL;
}
-
- kfree(nna_ar[nr_node_ids]);
- nna_ar[nr_node_ids] = NULL;
}
static void init_node_nr_active(struct wq_node_nr_active *nna)
@@ -5109,21 +5126,15 @@ static int alloc_node_nr_active(struct wq_node_nr_active **nna_ar)
struct wq_node_nr_active *nna;
int node;
- for_each_node(node) {
- nna = kzalloc_node(sizeof(*nna), GFP_KERNEL, node);
+ for_each_node_with_fallback(node) {
+ nna = kzalloc_node(sizeof(*nna), GFP_KERNEL,
+ node < nr_node_ids ? node : NUMA_NO_NODE);
if (!nna)
goto err_free;
init_node_nr_active(nna);
nna_ar[node] = nna;
}
- /* [nr_node_ids] is used as the fallback */
- nna = kzalloc_node(sizeof(*nna), GFP_KERNEL, NUMA_NO_NODE);
- if (!nna)
- goto err_free;
- init_node_nr_active(nna);
- nna_ar[nr_node_ids] = nna;
-
return 0;
err_free: