diff options
author | Mel Gorman <mgorman@suse.de> | 2014-06-04 19:10:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-04 19:54:08 -0400 |
commit | 664eeddeef6539247691197c1ac124d4aa872ab6 (patch) | |
tree | 568fa77ea4d8b525efeec73e398951b6089374f8 | |
parent | ea5e9539abf1258f23e725cb9cb25aa74efa29eb (diff) |
mm: page_alloc: use jump labels to avoid checking number_of_cpusets
If cpusets are not in use then we still check a global variable on every
page allocation. Use jump labels to avoid the overhead.
Signed-off-by: Mel Gorman <mgorman@suse.de>
Reviewed-by: Rik van Riel <riel@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Jan Kara <jack@suse.cz>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Hugh Dickins <hughd@google.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Theodore Ts'o <tytso@mit.edu>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | include/linux/cpuset.h | 29 | ||||
-rw-r--r-- | kernel/cpuset.c | 14 | ||||
-rw-r--r-- | mm/page_alloc.c | 3 |
3 files changed, 32 insertions, 14 deletions
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h index b19d3dc2e651..ade2390ffe92 100644 --- a/include/linux/cpuset.h +++ b/include/linux/cpuset.h | |||
@@ -12,10 +12,31 @@ | |||
12 | #include <linux/cpumask.h> | 12 | #include <linux/cpumask.h> |
13 | #include <linux/nodemask.h> | 13 | #include <linux/nodemask.h> |
14 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
15 | #include <linux/jump_label.h> | ||
15 | 16 | ||
16 | #ifdef CONFIG_CPUSETS | 17 | #ifdef CONFIG_CPUSETS |
17 | 18 | ||
18 | extern int number_of_cpusets; /* How many cpusets are defined in system? */ | 19 | extern struct static_key cpusets_enabled_key; |
20 | static inline bool cpusets_enabled(void) | ||
21 | { | ||
22 | return static_key_false(&cpusets_enabled_key); | ||
23 | } | ||
24 | |||
25 | static inline int nr_cpusets(void) | ||
26 | { | ||
27 | /* jump label reference count + the top-level cpuset */ | ||
28 | return static_key_count(&cpusets_enabled_key) + 1; | ||
29 | } | ||
30 | |||
31 | static inline void cpuset_inc(void) | ||
32 | { | ||
33 | static_key_slow_inc(&cpusets_enabled_key); | ||
34 | } | ||
35 | |||
36 | static inline void cpuset_dec(void) | ||
37 | { | ||
38 | static_key_slow_dec(&cpusets_enabled_key); | ||
39 | } | ||
19 | 40 | ||
20 | extern int cpuset_init(void); | 41 | extern int cpuset_init(void); |
21 | extern void cpuset_init_smp(void); | 42 | extern void cpuset_init_smp(void); |
@@ -32,13 +53,13 @@ extern int __cpuset_node_allowed_hardwall(int node, gfp_t gfp_mask); | |||
32 | 53 | ||
33 | static inline int cpuset_node_allowed_softwall(int node, gfp_t gfp_mask) | 54 | static inline int cpuset_node_allowed_softwall(int node, gfp_t gfp_mask) |
34 | { | 55 | { |
35 | return number_of_cpusets <= 1 || | 56 | return nr_cpusets() <= 1 || |
36 | __cpuset_node_allowed_softwall(node, gfp_mask); | 57 | __cpuset_node_allowed_softwall(node, gfp_mask); |
37 | } | 58 | } |
38 | 59 | ||
39 | static inline int cpuset_node_allowed_hardwall(int node, gfp_t gfp_mask) | 60 | static inline int cpuset_node_allowed_hardwall(int node, gfp_t gfp_mask) |
40 | { | 61 | { |
41 | return number_of_cpusets <= 1 || | 62 | return nr_cpusets() <= 1 || |
42 | __cpuset_node_allowed_hardwall(node, gfp_mask); | 63 | __cpuset_node_allowed_hardwall(node, gfp_mask); |
43 | } | 64 | } |
44 | 65 | ||
@@ -124,6 +145,8 @@ static inline void set_mems_allowed(nodemask_t nodemask) | |||
124 | 145 | ||
125 | #else /* !CONFIG_CPUSETS */ | 146 | #else /* !CONFIG_CPUSETS */ |
126 | 147 | ||
148 | static inline bool cpusets_enabled(void) { return false; } | ||
149 | |||
127 | static inline int cpuset_init(void) { return 0; } | 150 | static inline int cpuset_init(void) { return 0; } |
128 | static inline void cpuset_init_smp(void) {} | 151 | static inline void cpuset_init_smp(void) {} |
129 | 152 | ||
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 3d54c418bd06..130017843899 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -61,12 +61,7 @@ | |||
61 | #include <linux/cgroup.h> | 61 | #include <linux/cgroup.h> |
62 | #include <linux/wait.h> | 62 | #include <linux/wait.h> |
63 | 63 | ||
64 | /* | 64 | struct static_key cpusets_enabled_key __read_mostly = STATIC_KEY_INIT_FALSE; |
65 | * Tracks how many cpusets are currently defined in system. | ||
66 | * When there is only one cpuset (the root cpuset) we can | ||
67 | * short circuit some hooks. | ||
68 | */ | ||
69 | int number_of_cpusets __read_mostly; | ||
70 | 65 | ||
71 | /* See "Frequency meter" comments, below. */ | 66 | /* See "Frequency meter" comments, below. */ |
72 | 67 | ||
@@ -611,7 +606,7 @@ static int generate_sched_domains(cpumask_var_t **domains, | |||
611 | goto done; | 606 | goto done; |
612 | } | 607 | } |
613 | 608 | ||
614 | csa = kmalloc(number_of_cpusets * sizeof(cp), GFP_KERNEL); | 609 | csa = kmalloc(nr_cpusets() * sizeof(cp), GFP_KERNEL); |
615 | if (!csa) | 610 | if (!csa) |
616 | goto done; | 611 | goto done; |
617 | csn = 0; | 612 | csn = 0; |
@@ -1888,7 +1883,7 @@ static int cpuset_css_online(struct cgroup_subsys_state *css) | |||
1888 | if (is_spread_slab(parent)) | 1883 | if (is_spread_slab(parent)) |
1889 | set_bit(CS_SPREAD_SLAB, &cs->flags); | 1884 | set_bit(CS_SPREAD_SLAB, &cs->flags); |
1890 | 1885 | ||
1891 | number_of_cpusets++; | 1886 | cpuset_inc(); |
1892 | 1887 | ||
1893 | if (!test_bit(CGRP_CPUSET_CLONE_CHILDREN, &css->cgroup->flags)) | 1888 | if (!test_bit(CGRP_CPUSET_CLONE_CHILDREN, &css->cgroup->flags)) |
1894 | goto out_unlock; | 1889 | goto out_unlock; |
@@ -1939,7 +1934,7 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css) | |||
1939 | if (is_sched_load_balance(cs)) | 1934 | if (is_sched_load_balance(cs)) |
1940 | update_flag(CS_SCHED_LOAD_BALANCE, cs, 0); | 1935 | update_flag(CS_SCHED_LOAD_BALANCE, cs, 0); |
1941 | 1936 | ||
1942 | number_of_cpusets--; | 1937 | cpuset_dec(); |
1943 | clear_bit(CS_ONLINE, &cs->flags); | 1938 | clear_bit(CS_ONLINE, &cs->flags); |
1944 | 1939 | ||
1945 | mutex_unlock(&cpuset_mutex); | 1940 | mutex_unlock(&cpuset_mutex); |
@@ -1992,7 +1987,6 @@ int __init cpuset_init(void) | |||
1992 | if (!alloc_cpumask_var(&cpus_attach, GFP_KERNEL)) | 1987 | if (!alloc_cpumask_var(&cpus_attach, GFP_KERNEL)) |
1993 | BUG(); | 1988 | BUG(); |
1994 | 1989 | ||
1995 | number_of_cpusets = 1; | ||
1996 | return 0; | 1990 | return 0; |
1997 | } | 1991 | } |
1998 | 1992 | ||
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index b4381eaee715..a2955e101715 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -1921,7 +1921,8 @@ zonelist_scan: | |||
1921 | if (IS_ENABLED(CONFIG_NUMA) && zlc_active && | 1921 | if (IS_ENABLED(CONFIG_NUMA) && zlc_active && |
1922 | !zlc_zone_worth_trying(zonelist, z, allowednodes)) | 1922 | !zlc_zone_worth_trying(zonelist, z, allowednodes)) |
1923 | continue; | 1923 | continue; |
1924 | if ((alloc_flags & ALLOC_CPUSET) && | 1924 | if (cpusets_enabled() && |
1925 | (alloc_flags & ALLOC_CPUSET) && | ||
1925 | !cpuset_zone_allowed_softwall(zone, gfp_mask)) | 1926 | !cpuset_zone_allowed_softwall(zone, gfp_mask)) |
1926 | continue; | 1927 | continue; |
1927 | BUILD_BUG_ON(ALLOC_NO_WATERMARKS < NR_WMARK); | 1928 | BUILD_BUG_ON(ALLOC_NO_WATERMARKS < NR_WMARK); |