lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <ba75ff134a0a10af2c709bd7b51dbd8f66b65c49.1453754062.git.jbaron@akamai.com>
Date:	Mon, 25 Jan 2016 16:48:10 -0500
From:	Jason Baron <jbaron@...mai.com>
To:	akpm@...ux-foundation.org
Cc:	linux-kernel@...r.kernel.org, joe@...ches.com, peterz@...radead.org
Subject: [PATCH 1/3] jump_label: create jump_label_branch.h

The current jump_label.h header 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). So split
out struct static_key and static_key_[un]likely() definitions into a new
jump_label_branch.h header. This is consistant with a common usage pattern for
jump_label, where the branch locations are often separated from the branch
updates. This makes jump_label more includable.

Cc: Joe Perches <joe@...ches.com>
Cc: Peter Zijlstra <peterz@...radead.org>
Signed-off-by: Jason Baron <jbaron@...mai.com>
---
 include/linux/jump_label.h        | 181 +---------------------------------
 include/linux/jump_label_branch.h | 199 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 204 insertions(+), 176 deletions(-)
 create mode 100644 include/linux/jump_label_branch.h

diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h
index 0536524..8d5c932 100644
--- a/include/linux/jump_label.h
+++ b/include/linux/jump_label.h
@@ -65,17 +65,17 @@
  * Lacking toolchain and or architecture support, static keys fall back to a
  * simple conditional branch.
  *
+ * The static_branch_[un]likely() definitions are included in
+ * jump_label_branch.h such that it can be included in 'low' level .h files
+ * such as kernel.h.
+ *
  * Additional babbling in: Documentation/static-keys.txt
  */
 
-#if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_JUMP_LABEL)
-# define HAVE_JUMP_LABEL
-#endif
+#include <linux/jump_label_branch.h>
 
 #ifndef __ASSEMBLY__
 
-#include <linux/types.h>
-#include <linux/compiler.h>
 #include <linux/bug.h>
 
 extern bool static_key_initialized;
@@ -84,30 +84,6 @@ extern bool static_key_initialized;
 				    "%s used before call to jump_label_init", \
 				    __func__)
 
-#ifdef HAVE_JUMP_LABEL
-
-struct static_key {
-	atomic_t enabled;
-/* Set lsb bit to 1 if branch is default true, 0 ot */
-	struct jump_entry *entries;
-#ifdef CONFIG_MODULES
-	struct static_key_mod *next;
-#endif
-};
-
-#else
-struct static_key {
-	atomic_t enabled;
-};
-#endif	/* HAVE_JUMP_LABEL */
-#endif /* __ASSEMBLY__ */
-
-#ifdef HAVE_JUMP_LABEL
-#include <asm/jump_label.h>
-#endif
-
-#ifndef __ASSEMBLY__
-
 enum jump_label_type {
 	JUMP_LABEL_NOP = 0,
 	JUMP_LABEL_JMP,
@@ -115,19 +91,8 @@ enum jump_label_type {
 
 struct module;
 
-#include <linux/atomic.h>
-
-static inline int static_key_count(struct static_key *key)
-{
-	return atomic_read(&key->enabled);
-}
-
 #ifdef HAVE_JUMP_LABEL
 
-#define JUMP_TYPE_FALSE	0UL
-#define JUMP_TYPE_TRUE	1UL
-#define JUMP_TYPE_MASK	1UL
-
 static __always_inline bool static_key_false(struct static_key *key)
 {
 	return arch_static_branch(key, false);
@@ -153,13 +118,6 @@ extern void static_key_slow_inc(struct static_key *key);
 extern void static_key_slow_dec(struct static_key *key);
 extern void jump_label_apply_nops(struct module *mod);
 
-#define STATIC_KEY_INIT_TRUE					\
-	{ .enabled = ATOMIC_INIT(1),				\
-	  .entries = (void *)JUMP_TYPE_TRUE }
-#define STATIC_KEY_INIT_FALSE					\
-	{ .enabled = ATOMIC_INIT(0),				\
-	  .entries = (void *)JUMP_TYPE_FALSE }
-
 #else  /* !HAVE_JUMP_LABEL */
 
 static __always_inline void jump_label_init(void)
@@ -206,9 +164,6 @@ static inline int jump_label_apply_nops(struct module *mod)
 	return 0;
 }
 
-#define STATIC_KEY_INIT_TRUE	{ .enabled = ATOMIC_INIT(1) }
-#define STATIC_KEY_INIT_FALSE	{ .enabled = ATOMIC_INIT(0) }
-
 #endif	/* HAVE_JUMP_LABEL */
 
 #define STATIC_KEY_INIT STATIC_KEY_INIT_FALSE
@@ -234,132 +189,6 @@ static inline void static_key_disable(struct static_key *key)
 		static_key_slow_dec(key);
 }
 
-/* -------------------------------------------------------------------------- */
-
-/*
- * Two type wrappers around static_key, such that we can use compile time
- * type differentiation to emit the right code.
- *
- * All the below code is macros in order to play type games.
- */
-
-struct static_key_true {
-	struct static_key key;
-};
-
-struct static_key_false {
-	struct static_key key;
-};
-
-#define STATIC_KEY_TRUE_INIT  (struct static_key_true) { .key = STATIC_KEY_INIT_TRUE,  }
-#define STATIC_KEY_FALSE_INIT (struct static_key_false){ .key = STATIC_KEY_INIT_FALSE, }
-
-#define DEFINE_STATIC_KEY_TRUE(name)	\
-	struct static_key_true name = STATIC_KEY_TRUE_INIT
-
-#define DEFINE_STATIC_KEY_FALSE(name)	\
-	struct static_key_false name = STATIC_KEY_FALSE_INIT
-
-extern bool ____wrong_branch_error(void);
-
-#define static_key_enabled(x)							\
-({										\
-	if (!__builtin_types_compatible_p(typeof(*x), struct static_key) &&	\
-	    !__builtin_types_compatible_p(typeof(*x), struct static_key_true) &&\
-	    !__builtin_types_compatible_p(typeof(*x), struct static_key_false))	\
-		____wrong_branch_error();					\
-	static_key_count((struct static_key *)x) > 0;				\
-})
-
-#ifdef HAVE_JUMP_LABEL
-
-/*
- * Combine the right initial value (type) with the right branch order
- * to generate the desired result.
- *
- *
- * type\branch|	likely (1)	      |	unlikely (0)
- * -----------+-----------------------+------------------
- *            |                       |
- *  true (1)  |	   ...		      |	   ...
- *            |    NOP		      |	   JMP L
- *            |    <br-stmts>	      |	1: ...
- *            |	L: ...		      |
- *            |			      |
- *            |			      |	L: <br-stmts>
- *            |			      |	   jmp 1b
- *            |                       |
- * -----------+-----------------------+------------------
- *            |                       |
- *  false (0) |	   ...		      |	   ...
- *            |    JMP L	      |	   NOP
- *            |    <br-stmts>	      |	1: ...
- *            |	L: ...		      |
- *            |			      |
- *            |			      |	L: <br-stmts>
- *            |			      |	   jmp 1b
- *            |                       |
- * -----------+-----------------------+------------------
- *
- * The initial value is encoded in the LSB of static_key::entries,
- * type: 0 = false, 1 = true.
- *
- * The branch type is encoded in the LSB of jump_entry::key,
- * branch: 0 = unlikely, 1 = likely.
- *
- * This gives the following logic table:
- *
- *	enabled	type	branch	  instuction
- * -----------------------------+-----------
- *	0	0	0	| NOP
- *	0	0	1	| JMP
- *	0	1	0	| NOP
- *	0	1	1	| JMP
- *
- *	1	0	0	| JMP
- *	1	0	1	| NOP
- *	1	1	0	| JMP
- *	1	1	1	| NOP
- *
- * Which gives the following functions:
- *
- *   dynamic: instruction = enabled ^ branch
- *   static:  instruction = type ^ branch
- *
- * See jump_label_type() / jump_label_init_type().
- */
-
-#define static_branch_likely(x)							\
-({										\
-	bool branch;								\
-	if (__builtin_types_compatible_p(typeof(*x), struct static_key_true))	\
-		branch = !arch_static_branch(&(x)->key, true);			\
-	else if (__builtin_types_compatible_p(typeof(*x), struct static_key_false)) \
-		branch = !arch_static_branch_jump(&(x)->key, true);		\
-	else									\
-		branch = ____wrong_branch_error();				\
-	branch;									\
-})
-
-#define static_branch_unlikely(x)						\
-({										\
-	bool branch;								\
-	if (__builtin_types_compatible_p(typeof(*x), struct static_key_true))	\
-		branch = arch_static_branch_jump(&(x)->key, false);		\
-	else if (__builtin_types_compatible_p(typeof(*x), struct static_key_false)) \
-		branch = arch_static_branch(&(x)->key, false);			\
-	else									\
-		branch = ____wrong_branch_error();				\
-	branch;									\
-})
-
-#else /* !HAVE_JUMP_LABEL */
-
-#define static_branch_likely(x)		likely(static_key_enabled(&(x)->key))
-#define static_branch_unlikely(x)	unlikely(static_key_enabled(&(x)->key))
-
-#endif /* HAVE_JUMP_LABEL */
-
 /*
  * Advanced usage; refcount, branch is enabled when: count != 0
  */
diff --git a/include/linux/jump_label_branch.h b/include/linux/jump_label_branch.h
new file mode 100644
index 0000000..d48611a
--- /dev/null
+++ b/include/linux/jump_label_branch.h
@@ -0,0 +1,199 @@
+#ifndef _LINUX_JUMP_LABEL_BRANCH_H
+#define _LINUX_JUMP_LABEL_BRANCH_H
+
+/*
+ * jump_label_branch.h: provides struct static_key and static_branch_[un]likely
+ *
+ * Users of the jump label interfaces usually just include jump_label.h.
+ * However, some of the #includes in jump_label.h are problematic for inclusion
+ * in basic headers such as kernel.h. So split off static_branch_[un]likely
+ * since this is typically all we need in a .h file. For further info about
+ * the jump_label infrastructure see jump_label.h
+ */
+
+#if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_JUMP_LABEL)
+# define HAVE_JUMP_LABEL
+#endif
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+
+#ifdef HAVE_JUMP_LABEL
+
+struct static_key {
+	atomic_t enabled;
+/* Set lsb bit to 1 if branch is default true, 0 ot */
+	struct jump_entry *entries;
+#ifdef CONFIG_MODULES
+	struct static_key_mod *next;
+#endif
+};
+
+#else
+struct static_key {
+	atomic_t enabled;
+};
+#endif  /* HAVE_JUMP_LABEL */
+#endif /* __ASSEMBLY__ */
+
+#ifdef HAVE_JUMP_LABEL
+#include <asm/jump_label.h>
+#endif
+
+#ifndef __ASSEMBLY__
+
+#include <linux/atomic.h>
+
+static inline int static_key_count(struct static_key *key)
+{
+	return atomic_read(&key->enabled);
+}
+
+#ifdef HAVE_JUMP_LABEL
+
+#define JUMP_TYPE_FALSE 0UL
+#define JUMP_TYPE_TRUE  1UL
+#define JUMP_TYPE_MASK  1UL
+
+#define STATIC_KEY_INIT_TRUE                                    \
+	{ .enabled = ATOMIC_INIT(1),                            \
+	  .entries = (void *)JUMP_TYPE_TRUE }
+#define STATIC_KEY_INIT_FALSE                                   \
+	{ .enabled = ATOMIC_INIT(0),                            \
+	  .entries = (void *)JUMP_TYPE_FALSE }
+#else
+
+#define STATIC_KEY_INIT_TRUE    { .enabled = ATOMIC_INIT(1) }
+#define STATIC_KEY_INIT_FALSE   { .enabled = ATOMIC_INIT(0) }
+
+#endif
+
+/*
+ * Two type wrappers around static_key, such that we can use compile time
+ * type differentiation to emit the right code.
+ *
+ * All the below code is macros in order to play type games.
+ */
+
+struct static_key_true {
+	struct static_key key;
+};
+
+struct static_key_false {
+	struct static_key key;
+};
+
+#define STATIC_KEY_TRUE_INIT  (struct static_key_true) { .key = STATIC_KEY_INIT_TRUE,  }
+#define STATIC_KEY_FALSE_INIT (struct static_key_false){ .key = STATIC_KEY_INIT_FALSE, }
+
+#define DEFINE_STATIC_KEY_TRUE(name)	\
+	struct static_key_true name = STATIC_KEY_TRUE_INIT
+
+#define DEFINE_STATIC_KEY_FALSE(name)	\
+	struct static_key_false name = STATIC_KEY_FALSE_INIT
+
+extern bool ____wrong_branch_error(void);
+
+#define static_key_enabled(x)							\
+({										\
+	if (!__builtin_types_compatible_p(typeof(*x), struct static_key) &&	\
+	    !__builtin_types_compatible_p(typeof(*x), struct static_key_true) &&\
+	    !__builtin_types_compatible_p(typeof(*x), struct static_key_false))	\
+		____wrong_branch_error();					\
+	static_key_count((struct static_key *)x) > 0;				\
+})
+
+#ifdef HAVE_JUMP_LABEL
+
+/*
+ * Combine the right initial value (type) with the right branch order
+ * to generate the desired result.
+ *
+ *
+ * type\branch|	likely (1)	      |	unlikely (0)
+ * -----------+-----------------------+------------------
+ *            |                       |
+ *  true (1)  |	   ...		      |	   ...
+ *            |    NOP		      |	   JMP L
+ *            |    <br-stmts>	      |	1: ...
+ *            |	L: ...		      |
+ *            |			      |
+ *            |			      |	L: <br-stmts>
+ *            |			      |	   jmp 1b
+ *            |                       |
+ * -----------+-----------------------+------------------
+ *            |                       |
+ *  false (0) |	   ...		      |	   ...
+ *            |    JMP L	      |	   NOP
+ *            |    <br-stmts>	      |	1: ...
+ *            |	L: ...		      |
+ *            |			      |
+ *            |			      |	L: <br-stmts>
+ *            |			      |	   jmp 1b
+ *            |                       |
+ * -----------+-----------------------+------------------
+ *
+ * The initial value is encoded in the LSB of static_key::entries,
+ * type: 0 = false, 1 = true.
+ *
+ * The branch type is encoded in the LSB of jump_entry::key,
+ * branch: 0 = unlikely, 1 = likely.
+ *
+ * This gives the following logic table:
+ *
+ *	enabled	type	branch	  instuction
+ * -----------------------------+-----------
+ *	0	0	0	| NOP
+ *	0	0	1	| JMP
+ *	0	1	0	| NOP
+ *	0	1	1	| JMP
+ *
+ *	1	0	0	| JMP
+ *	1	0	1	| NOP
+ *	1	1	0	| JMP
+ *	1	1	1	| NOP
+ *
+ * Which gives the following functions:
+ *
+ *   dynamic: instruction = enabled ^ branch
+ *   static:  instruction = type ^ branch
+ *
+ * See jump_label_type() / jump_label_init_type().
+ */
+
+#define static_branch_likely(x)							\
+({										\
+	bool branch;								\
+	if (__builtin_types_compatible_p(typeof(*x), struct static_key_true))	\
+		branch = !arch_static_branch(&(x)->key, true);			\
+	else if (__builtin_types_compatible_p(typeof(*x), struct static_key_false)) \
+		branch = !arch_static_branch_jump(&(x)->key, true);		\
+	else									\
+		branch = ____wrong_branch_error();				\
+	branch;									\
+})
+
+#define static_branch_unlikely(x)						\
+({										\
+	bool branch;								\
+	if (__builtin_types_compatible_p(typeof(*x), struct static_key_true))	\
+		branch = arch_static_branch_jump(&(x)->key, false);		\
+	else if (__builtin_types_compatible_p(typeof(*x), struct static_key_false)) \
+		branch = arch_static_branch(&(x)->key, false);			\
+	else									\
+		branch = ____wrong_branch_error();				\
+	branch;									\
+})
+
+#else /* !HAVE_JUMP_LABEL */
+
+#define static_branch_likely(x)		likely(static_key_enabled(&(x)->key))
+#define static_branch_unlikely(x)	unlikely(static_key_enabled(&(x)->key))
+
+#endif /* HAVE_JUMP_LABEL */
+
+#endif /* __ASSEMBLY__ */
+
+#endif
-- 
2.6.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ