From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753174AbcISRVs (ORCPT ); Mon, 19 Sep 2016 13:21:48 -0400 Received: from foss.arm.com ([217.140.101.70]:40334 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753124AbcISRVp (ORCPT ); Mon, 19 Sep 2016 13:21:45 -0400 From: Marc Zyngier To: linux-kernel@vger.kernel.org Cc: Jason Baron , Jonathan Corbet , Peter Zijlstra , Christoffer Dall , Vladimir Murzin , Catalin Marinas Subject: [PATCH 1/2] jump_labels: Add API to deal with keys embedded in structures Date: Mon, 19 Sep 2016 18:21:27 +0100 Message-Id: <1474305688-22553-2-git-send-email-marc.zyngier@arm.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1474305688-22553-1-git-send-email-marc.zyngier@arm.com> References: <1474305688-22553-1-git-send-email-marc.zyngier@arm.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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