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: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Mon, 19 Sep 2016 18:21:27 +0100
From:   Marc Zyngier <marc.zyngier@....com>
To:     linux-kernel@...r.kernel.org
Cc:     Jason Baron <jbaron@...mai.com>, Jonathan Corbet <corbet@....net>,
        Peter Zijlstra <peterz@...radead.org>,
        Christoffer Dall <christoffer.dall@...aro.org>,
        Vladimir Murzin <vladimir.murzin@....com>,
        Catalin Marinas <catalin.marinas@....com>
Subject: [PATCH 1/2] jump_labels: Add API to deal with keys embedded in structures

It is desirable to allow static keys to be integrated in structures,
as it can lead do slightly more readable code. But the current API
only provides DEFINE_STATIC_KEY_TRUE/FALSE, which is not exactly
nice and leads to the following idiom:

	static struct {
		int			foo;
		struct static_key_false	key;
	} bar = {
		.key	= STATIC_KEY_FALSE_INIT,
	};

	[...]

	if (static_branch_unlikely(&bar.key))
		foo = -1;

which doesn't follow the recommended API, and uses the internals
of the static key implementation.

This patch introduces DECLARE_STATIC_KEY_TRUE/FALSE, as well as
INIT_STATIC_KEY_TRUE/FALSE, which abstract such construct and
allow the internals to evolve without having to fix everything else:

	static struct {
		int			 foo;
		DECLARE_STATIC_KEY_FALSE(key);
	} bar = {
		INIT_STATIC_KEY_FALSE(.key),
	};

Signed-off-by: Marc Zyngier <marc.zyngier@....com>
---
 Documentation/static-keys.txt | 19 +++++++++++++++++++
 include/linux/jump_label.h    | 21 ++++++++++++++++++---
 2 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/Documentation/static-keys.txt b/Documentation/static-keys.txt
index ea8d7b4..a2fedb2 100644
--- a/Documentation/static-keys.txt
+++ b/Documentation/static-keys.txt
@@ -15,6 +15,10 @@ The updated API replacements are:
 
 DEFINE_STATIC_KEY_TRUE(key);
 DEFINE_STATIC_KEY_FALSE(key);
+DECLARE_STATIC_KEY_TRUE(key);
+DECLARE_STATIC_KEY_FALSE(key);
+INIT_STATIC_KEY_TRUE(key);
+INIT_STATIC_KEY_FALSE(key);
 DEFINE_STATIC_KEY_ARRAY_TRUE(keys, count);
 DEFINE_STATIC_KEY_ARRAY_FALSE(keys, count);
 static_branch_likely()
@@ -142,6 +146,21 @@ static_branch_inc(), will change the branch back to true. Likewise, if the
 key is initialized false, a 'static_branch_inc()', will change the branch to
 true. And then a 'static_branch_dec()', will again make the branch false.
 
+Should the key be declared in a structure and required to be
+initialized when such structure is defined, the following construct
+can be used:
+
+    	struct foo {
+    		DECLARE_STATIC_KEY_FALSE(key);
+    	};
+
+	static struct foo bar = {
+    		INIT_STATIC_KEY_FALSE(.key),
+    	};
+
+(respectively DECLARE_STATIC_KEY_TRUE/INIT_STATIC_KEY_TRUE for the
+opposite case).
+
 Where an array of keys is required, it can be defined as:
 
 	DEFINE_STATIC_KEY_ARRAY_TRUE(keys, count);
diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h
index a534c7f..10ee414 100644
--- a/include/linux/jump_label.h
+++ b/include/linux/jump_label.h
@@ -21,6 +21,10 @@
  *
  * DEFINE_STATIC_KEY_TRUE(key);
  * DEFINE_STATIC_KEY_FALSE(key);
+ * DECLARE_STATIC_KEY_TRUE(key);
+ * DECLARE_STATIC_KEY_FALSE(key);
+ * INIT_STATIC_KEY_TRUE(key);
+ * INIT_STATIC_KEY_FALSE(key);
  * DEFINE_STATIC_KEY_ARRAY_TRUE(keys, count);
  * DEFINE_STATIC_KEY_ARRAY_FALSE(keys, count);
  * static_branch_likely()
@@ -36,7 +40,10 @@
  * "if (static_branch_unlikely(&key))", in which case we will generate an
  * unconditional branch to the out-of-line true branch. Keys that are
  * initially true or false can be using in both static_branch_unlikely()
- * and static_branch_likely() statements.
+ * and static_branch_likely() statements. DECLARE_STATIC_KEY_TRUE/FALSE
+ * can be used to declare a key that will be defined somewhere else.
+ * INIT_STATIC_KEY_TRUE/FALSE initialize a static key that can be declared
+ * in another structure.
  *
  * At runtime we can change the branch target by setting the key
  * to true via a call to static_branch_enable(), or false using
@@ -266,11 +273,19 @@ struct static_key_false {
 #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 DECLARE_STATIC_KEY_TRUE(name)	struct static_key_true name
+
+#define DECLARE_STATIC_KEY_FALSE(name)	struct static_key_false name
+
+#define INIT_STATIC_KEY_TRUE(name)	name = STATIC_KEY_TRUE_INIT
+
+#define INIT_STATIC_KEY_FALSE(name)	name = STATIC_KEY_FALSE_INIT
+
 #define DEFINE_STATIC_KEY_TRUE(name)	\
-	struct static_key_true name = STATIC_KEY_TRUE_INIT
+	DECLARE_STATIC_KEY_TRUE(name) = STATIC_KEY_TRUE_INIT
 
 #define DEFINE_STATIC_KEY_FALSE(name)	\
-	struct static_key_false name = STATIC_KEY_FALSE_INIT
+	DECLARE_STATIC_KEY_FALSE(name) = STATIC_KEY_FALSE_INIT
 
 #define DEFINE_STATIC_KEY_ARRAY_TRUE(name, count)		\
 	struct static_key_true name[count] = {			\
-- 
2.1.4

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ