aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Baron <jbaron@akamai.com>2016-08-03 16:46:36 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-08-04 08:50:07 -0400
commit1f69bf9c6137602cd028c96b4f8329121ec89231 (patch)
tree0ea0db8df6f0ce830a3f3e83c52368785ccadc56
parentddb45306018f6be5661c4f66c12ffbbecf9bcb9f (diff)
jump_label: remove bug.h, atomic.h dependencies for HAVE_JUMP_LABEL
The current jump_label.h includes bug.h for things such as WARN_ON(). This makes the header problematic for inclusion by kernel.h or any headers that kernel.h includes, since bug.h includes kernel.h (circular dependency). The inclusion of atomic.h is similarly problematic. Thus, this should make jump_label.h 'includable' from most places. Link: http://lkml.kernel.org/r/7060ce35ddd0d20b33bf170685e6b0fab816bdf2.1467837322.git.jbaron@akamai.com Signed-off-by: Jason Baron <jbaron@akamai.com> Cc: "David S. Miller" <davem@davemloft.net> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Chris Metcalf <cmetcalf@mellanox.com> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Joe Perches <joe@perches.com> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--include/linux/jump_label.h46
-rw-r--r--kernel/jump_label.c53
2 files changed, 76 insertions, 23 deletions
diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h
index 68904469fba1..661af564fae8 100644
--- a/include/linux/jump_label.h
+++ b/include/linux/jump_label.h
@@ -76,7 +76,6 @@
76 76
77#include <linux/types.h> 77#include <linux/types.h>
78#include <linux/compiler.h> 78#include <linux/compiler.h>
79#include <linux/bug.h>
80 79
81extern bool static_key_initialized; 80extern bool static_key_initialized;
82 81
@@ -115,20 +114,8 @@ enum jump_label_type {
115 114
116struct module; 115struct module;
117 116
118#include <linux/atomic.h>
119
120#ifdef HAVE_JUMP_LABEL 117#ifdef HAVE_JUMP_LABEL
121 118
122static inline int static_key_count(struct static_key *key)
123{
124 /*
125 * -1 means the first static_key_slow_inc() is in progress.
126 * static_key_enabled() must return true, so return 1 here.
127 */
128 int n = atomic_read(&key->enabled);
129 return n >= 0 ? n : 1;
130}
131
132#define JUMP_TYPE_FALSE 0UL 119#define JUMP_TYPE_FALSE 0UL
133#define JUMP_TYPE_TRUE 1UL 120#define JUMP_TYPE_TRUE 1UL
134#define JUMP_TYPE_MASK 1UL 121#define JUMP_TYPE_MASK 1UL
@@ -157,16 +144,29 @@ extern int jump_label_text_reserved(void *start, void *end);
157extern void static_key_slow_inc(struct static_key *key); 144extern void static_key_slow_inc(struct static_key *key);
158extern void static_key_slow_dec(struct static_key *key); 145extern void static_key_slow_dec(struct static_key *key);
159extern void jump_label_apply_nops(struct module *mod); 146extern void jump_label_apply_nops(struct module *mod);
147extern int static_key_count(struct static_key *key);
148extern void static_key_enable(struct static_key *key);
149extern void static_key_disable(struct static_key *key);
160 150
151/*
152 * We should be using ATOMIC_INIT() for initializing .enabled, but
153 * the inclusion of atomic.h is problematic for inclusion of jump_label.h
154 * in 'low-level' headers. Thus, we are initializing .enabled with a
155 * raw value, but have added a BUILD_BUG_ON() to catch any issues in
156 * jump_label_init() see: kernel/jump_label.c.
157 */
161#define STATIC_KEY_INIT_TRUE \ 158#define STATIC_KEY_INIT_TRUE \
162 { .enabled = ATOMIC_INIT(1), \ 159 { .enabled = { 1 }, \
163 .entries = (void *)JUMP_TYPE_TRUE } 160 .entries = (void *)JUMP_TYPE_TRUE }
164#define STATIC_KEY_INIT_FALSE \ 161#define STATIC_KEY_INIT_FALSE \
165 { .enabled = ATOMIC_INIT(0), \ 162 { .enabled = { 0 }, \
166 .entries = (void *)JUMP_TYPE_FALSE } 163 .entries = (void *)JUMP_TYPE_FALSE }
167 164
168#else /* !HAVE_JUMP_LABEL */ 165#else /* !HAVE_JUMP_LABEL */
169 166
167#include <linux/atomic.h>
168#include <linux/bug.h>
169
170static inline int static_key_count(struct static_key *key) 170static inline int static_key_count(struct static_key *key)
171{ 171{
172 return atomic_read(&key->enabled); 172 return atomic_read(&key->enabled);
@@ -216,14 +216,6 @@ static inline int jump_label_apply_nops(struct module *mod)
216 return 0; 216 return 0;
217} 217}
218 218
219#define STATIC_KEY_INIT_TRUE { .enabled = ATOMIC_INIT(1) }
220#define STATIC_KEY_INIT_FALSE { .enabled = ATOMIC_INIT(0) }
221
222#endif /* HAVE_JUMP_LABEL */
223
224#define STATIC_KEY_INIT STATIC_KEY_INIT_FALSE
225#define jump_label_enabled static_key_enabled
226
227static inline void static_key_enable(struct static_key *key) 219static inline void static_key_enable(struct static_key *key)
228{ 220{
229 int count = static_key_count(key); 221 int count = static_key_count(key);
@@ -244,6 +236,14 @@ static inline void static_key_disable(struct static_key *key)
244 static_key_slow_dec(key); 236 static_key_slow_dec(key);
245} 237}
246 238
239#define STATIC_KEY_INIT_TRUE { .enabled = ATOMIC_INIT(1) }
240#define STATIC_KEY_INIT_FALSE { .enabled = ATOMIC_INIT(0) }
241
242#endif /* HAVE_JUMP_LABEL */
243
244#define STATIC_KEY_INIT STATIC_KEY_INIT_FALSE
245#define jump_label_enabled static_key_enabled
246
247/* -------------------------------------------------------------------------- */ 247/* -------------------------------------------------------------------------- */
248 248
249/* 249/*
diff --git a/kernel/jump_label.c b/kernel/jump_label.c
index 0dbea887d625..f19aa02a8f48 100644
--- a/kernel/jump_label.c
+++ b/kernel/jump_label.c
@@ -14,6 +14,7 @@
14#include <linux/err.h> 14#include <linux/err.h>
15#include <linux/static_key.h> 15#include <linux/static_key.h>
16#include <linux/jump_label_ratelimit.h> 16#include <linux/jump_label_ratelimit.h>
17#include <linux/bug.h>
17 18
18#ifdef HAVE_JUMP_LABEL 19#ifdef HAVE_JUMP_LABEL
19 20
@@ -56,6 +57,49 @@ jump_label_sort_entries(struct jump_entry *start, struct jump_entry *stop)
56 57
57static void jump_label_update(struct static_key *key); 58static void jump_label_update(struct static_key *key);
58 59
60/*
61 * There are similar definitions for the !HAVE_JUMP_LABEL case in jump_label.h.
62 * The use of 'atomic_read()' requires atomic.h and its problematic for some
63 * kernel headers such as kernel.h and others. Since static_key_count() is not
64 * used in the branch statements as it is for the !HAVE_JUMP_LABEL case its ok
65 * to have it be a function here. Similarly, for 'static_key_enable()' and
66 * 'static_key_disable()', which require bug.h. This should allow jump_label.h
67 * to be included from most/all places for HAVE_JUMP_LABEL.
68 */
69int static_key_count(struct static_key *key)
70{
71 /*
72 * -1 means the first static_key_slow_inc() is in progress.
73 * static_key_enabled() must return true, so return 1 here.
74 */
75 int n = atomic_read(&key->enabled);
76
77 return n >= 0 ? n : 1;
78}
79EXPORT_SYMBOL_GPL(static_key_count);
80
81void static_key_enable(struct static_key *key)
82{
83 int count = static_key_count(key);
84
85 WARN_ON_ONCE(count < 0 || count > 1);
86
87 if (!count)
88 static_key_slow_inc(key);
89}
90EXPORT_SYMBOL_GPL(static_key_enable);
91
92void static_key_disable(struct static_key *key)
93{
94 int count = static_key_count(key);
95
96 WARN_ON_ONCE(count < 0 || count > 1);
97
98 if (count)
99 static_key_slow_dec(key);
100}
101EXPORT_SYMBOL_GPL(static_key_disable);
102
59void static_key_slow_inc(struct static_key *key) 103void static_key_slow_inc(struct static_key *key)
60{ 104{
61 int v, v1; 105 int v, v1;
@@ -235,6 +279,15 @@ void __init jump_label_init(void)
235 struct static_key *key = NULL; 279 struct static_key *key = NULL;
236 struct jump_entry *iter; 280 struct jump_entry *iter;
237 281
282 /*
283 * Since we are initializing the static_key.enabled field with
284 * with the 'raw' int values (to avoid pulling in atomic.h) in
285 * jump_label.h, let's make sure that is safe. There are only two
286 * cases to check since we initialize to 0 or 1.
287 */
288 BUILD_BUG_ON((int)ATOMIC_INIT(0) != 0);
289 BUILD_BUG_ON((int)ATOMIC_INIT(1) != 1);
290
238 jump_label_lock(); 291 jump_label_lock();
239 jump_label_sort_entries(iter_start, iter_stop); 292 jump_label_sort_entries(iter_start, iter_stop);
240 293