Currently, get_unbound_pool() uses kzalloc() to allocate the worker pool. Actually, we can use the right node to do the allocation, achieving local memory access. This patch selects target node first, and uses kzalloc_node() instead.
Showing the changes to kernel/workqueue.c (1 of 1 file). Show all
Unified · Split
| @@ -3199,6 +3199,7 @@ static struct worker_pool *get_unbound_pool(const struct workqueue_attrs *attrs) · 3198 unmodified lines | ||
| 3199 | 3199 | u32 hash = wqattrs_hash(attrs); |
| 3200 | 3200 | struct worker_pool *pool; |
| 3201 | 3201 | int node; |
| 3202 | + int target_node = NUMA_NO_NODE; | |
| 3202 | 3203 | |
| 3203 | 3204 | lockdep_assert_held(&wq_pool_mutex); |
| 3204 | 3205 | |
| @@ -3210,13 +3211,25 @@ static struct worker_pool *get_unbound_pool(const struct workqueue_attrs *attrs) · 5 unmodified lines | ||
| 3210 | 3211 | } |
| 3211 | 3212 | } |
| 3212 | 3213 | |
| 3214 | + /* if cpumask is contained inside a NUMA node, we belong to that node */ | |
| 3215 | + if (wq_numa_enabled) { | |
| 3216 | + for_each_node(node) { | |
| 3217 | + if (cpumask_subset(attrs->cpumask, | |
| 3218 | + wq_numa_possible_cpumask[node])) { | |
| 3219 | + target_node = node; | |
| 3220 | + break; | |
| 3221 | + } | |
| 3222 | + } | |
| 3223 | + } | |
| 3224 | + | |
| 3213 | 3225 | /* nope, create a new one */ |
| 3214 | − pool = kzalloc(sizeof(*pool), GFP_KERNEL); | |
| 3226 | + pool = kzalloc_node(sizeof(*pool), GFP_KERNEL, target_node); | |
| 3215 | 3227 | if (!pool || init_worker_pool(pool) < 0) |
| 3216 | 3228 | goto fail; |
| 3217 | 3229 | |
| 3218 | 3230 | lockdep_set_subclass(&pool->lock, 1); /* see put_pwq() */ |
| 3219 | 3231 | copy_workqueue_attrs(pool->attrs, attrs); |
| 3232 | + pool->node = target_node; | |
| 3220 | 3233 | |
| 3221 | 3234 | /* |
| 3222 | 3235 | * no_numa isn't a worker_pool attribute, always clear it. See |
| @@ -3224,17 +3237,6 @@ static struct worker_pool *get_unbound_pool(const struct workqueue_attrs *attrs) · 1 unmodified line | ||
| 3224 | 3237 | */ |
| 3225 | 3238 | pool->attrs->no_numa = false; |
| 3226 | 3239 | |
| 3227 | − /* if cpumask is contained inside a NUMA node, we belong to that node */ | |
| 3228 | − if (wq_numa_enabled) { | |
| 3229 | − for_each_node(node) { | |
| 3230 | − if (cpumask_subset(pool->attrs->cpumask, | |
| 3231 | − wq_numa_possible_cpumask[node])) { | |
| 3232 | − pool->node = node; | |
| 3233 | − break; | |
| 3234 | − } | |
| 3235 | − } | |
| 3236 | − } | |
| 3237 | − | |
| 3238 | 3240 | if (worker_pool_assign_id(pool) < 0) |
| 3239 | 3241 | goto fail; |
| 3240 | 3242 | |