workqueue: Allocate the unbound pool using local node memory
authorXunlei Pang <pang.xunlei@linaro.org>
Fri, 9 Oct 2015 03:53:12 +0000 (11:53 +0800)
committerTejun Heo <tj@kernel.org>
Mon, 12 Oct 2015 16:17:31 +0000 (12:17 -0400)
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.

Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: Tejun Heo <tj@kernel.org>
kernel/workqueue.c

index ca71582fcfab29ec708746eab636c325b9caef15..96d37473504049432884b6275b8a7c58165e238e 100644 (file)
@@ -3199,6 +3199,7 @@ static struct worker_pool *get_unbound_pool(const struct workqueue_attrs *attrs)
        u32 hash = wqattrs_hash(attrs);
        struct worker_pool *pool;
        int node;
+       int target_node = NUMA_NO_NODE;
 
        lockdep_assert_held(&wq_pool_mutex);
 
@@ -3210,13 +3211,25 @@ static struct worker_pool *get_unbound_pool(const struct workqueue_attrs *attrs)
                }
        }
 
+       /* if cpumask is contained inside a NUMA node, we belong to that node */
+       if (wq_numa_enabled) {
+               for_each_node(node) {
+                       if (cpumask_subset(attrs->cpumask,
+                                          wq_numa_possible_cpumask[node])) {
+                               target_node = node;
+                               break;
+                       }
+               }
+       }
+
        /* nope, create a new one */
-       pool = kzalloc(sizeof(*pool), GFP_KERNEL);
+       pool = kzalloc_node(sizeof(*pool), GFP_KERNEL, target_node);
        if (!pool || init_worker_pool(pool) < 0)
                goto fail;
 
        lockdep_set_subclass(&pool->lock, 1);   /* see put_pwq() */
        copy_workqueue_attrs(pool->attrs, attrs);
+       pool->node = target_node;
 
        /*
         * 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)
         */
        pool->attrs->no_numa = false;
 
-       /* if cpumask is contained inside a NUMA node, we belong to that node */
-       if (wq_numa_enabled) {
-               for_each_node(node) {
-                       if (cpumask_subset(pool->attrs->cpumask,
-                                          wq_numa_possible_cpumask[node])) {
-                               pool->node = node;
-                               break;
-                       }
-               }
-       }
-
        if (worker_pool_assign_id(pool) < 0)
                goto fail;