[v2,1/3] jump_label: Add static_key_fast_inc()

Message ID 20221103212524.865762-2-dima@arista.com
State New
Headers
Series net/tcp: Dynamically disable TCP-MD5 static key |

Commit Message

Dmitry Safonov Nov. 3, 2022, 9:25 p.m. UTC
  A helper to add another user for an existing enabled static key.

Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Jason Baron <jbaron@akamai.com>
Cc: Josh Poimboeuf <jpoimboe@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Suggested-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Dmitry Safonov <dima@arista.com>
---
 include/linux/jump_label.h | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)
  

Comments

Peter Zijlstra Nov. 3, 2022, 9:41 p.m. UTC | #1
On Thu, Nov 03, 2022 at 09:25:22PM +0000, Dmitry Safonov wrote:
> A helper to add another user for an existing enabled static key.

Utter lack of clue what for.

> +/***
> + * static_key_fast_inc - adds a user for a static key
> + * @key: static key that must be already enabled
> + *
> + * The caller must make sure that the static key can't get disabled while
> + * in this function. It doesn't patch jump labels, only adds a user to
> + * an already enabled static key.
> + */
> +static inline void static_key_fast_inc(struct static_key *key)
> +{
> +	STATIC_KEY_CHECK_USE(key);
> +	WARN_ON_ONCE(atomic_read(&key->enabled) < 1);
> +	atomic_inc(&key->enabled);
> +}

And no, that's racy as heck. We have things like atomic_inc_not_zero(),
I suggest looking into it.
  
kernel test robot Nov. 3, 2022, 11:46 p.m. UTC | #2
Hi Dmitry,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on f2f32f8af2b0ca9d619e5183eae3eed431793baf]

url:    https://github.com/intel-lab-lkp/linux/commits/Dmitry-Safonov/net-tcp-Dynamically-disable-TCP-MD5-static-key/20221104-052738
base:   f2f32f8af2b0ca9d619e5183eae3eed431793baf
patch link:    https://lore.kernel.org/r/20221103212524.865762-2-dima%40arista.com
patch subject: [PATCH v2 1/3] jump_label: Add static_key_fast_inc()
config: powerpc-allyesconfig
compiler: powerpc-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/bff5ecacd7c0f1e5d610c025726a6c5cb992e828
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Dmitry-Safonov/net-tcp-Dynamically-disable-TCP-MD5-static-key/20221104-052738
        git checkout bff5ecacd7c0f1e5d610c025726a6c5cb992e828
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=powerpc prepare

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All error/warnings (new ones prefixed by >>):

   In file included from arch/powerpc/include/asm/page.h:256,
                    from arch/powerpc/include/asm/thread_info.h:13,
                    from include/linux/thread_info.h:60,
                    from arch/powerpc/include/asm/ptrace.h:328,
                    from arch/powerpc/include/asm/hw_irq.h:12,
                    from arch/powerpc/include/asm/irqflags.h:12,
                    from include/linux/irqflags.h:16,
                    from include/asm-generic/cmpxchg-local.h:6,
                    from arch/powerpc/include/asm/cmpxchg.h:526,
                    from arch/powerpc/include/asm/atomic.h:11,
                    from include/linux/atomic.h:7,
                    from include/linux/jump_label.h:78,
                    from include/linux/dynamic_debug.h:6,
                    from include/linux/printk.h:566,
                    from include/asm-generic/bug.h:22,
                    from arch/powerpc/include/asm/bug.h:158,
                    from include/linux/bug.h:5,
                    from include/linux/fortify-string.h:5,
                    from include/linux/string.h:253,
                    from include/linux/uuid.h:12,
                    from include/linux/mod_devicetable.h:13,
                    from scripts/mod/devicetable-offsets.c:3:
   arch/powerpc/include/asm/page_32.h: In function 'clear_page':
>> arch/powerpc/include/asm/page_32.h:48:9: error: implicit declaration of function 'WARN_ON' [-Werror=implicit-function-declaration]
      48 |         WARN_ON((unsigned long)addr & (L1_CACHE_BYTES - 1));
         |         ^~~~~~~
   In file included from arch/powerpc/include/asm/hw_breakpoint.h:12,
                    from arch/powerpc/include/asm/processor.h:43,
                    from arch/powerpc/include/asm/thread_info.h:46:
   arch/powerpc/include/asm/cpu_has_feature.h: At top level:
>> arch/powerpc/include/asm/cpu_has_feature.h:21:31: error: array type has incomplete element type 'struct static_key_true'
      21 | extern struct static_key_true cpu_feature_keys[NUM_CPU_FTR_KEYS];
         |                               ^~~~~~~~~~~~~~~~
   arch/powerpc/include/asm/cpu_has_feature.h: In function 'cpu_has_feature':
>> arch/powerpc/include/asm/cpu_has_feature.h:32:14: error: 'static_key_initialized' undeclared (first use in this function)
      32 |         if (!static_key_initialized) {
         |              ^~~~~~~~~~~~~~~~~~~~~~
   arch/powerpc/include/asm/cpu_has_feature.h:32:14: note: each undeclared identifier is reported only once for each function it appears in
>> arch/powerpc/include/asm/cpu_has_feature.h:46:16: error: implicit declaration of function 'static_branch_likely' [-Werror=implicit-function-declaration]
      46 |         return static_branch_likely(&cpu_feature_keys[i]);
         |                ^~~~~~~~~~~~~~~~~~~~
>> arch/powerpc/include/asm/cpu_has_feature.h:25:13: warning: variable 'i' set but not used [-Wunused-but-set-variable]
      25 |         int i;
         |             ^
   include/linux/thread_info.h: In function 'check_copy_size':
>> include/linux/thread_info.h:233:13: error: implicit declaration of function 'WARN_ON_ONCE' [-Werror=implicit-function-declaration]
     233 |         if (WARN_ON_ONCE(bytes > INT_MAX))
         |             ^~~~~~~~~~~~
   include/linux/jump_label.h: In function 'static_key_fast_inc':
   include/linux/jump_label.h:83:35: error: implicit declaration of function 'WARN' [-Werror=implicit-function-declaration]
      83 | #define STATIC_KEY_CHECK_USE(key) WARN(!static_key_initialized,               \
         |                                   ^~~~
   include/linux/jump_label.h:250:9: note: in expansion of macro 'STATIC_KEY_CHECK_USE'
     250 |         STATIC_KEY_CHECK_USE(key);
         |         ^~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors
   make[2]: *** [scripts/Makefile.build:118: scripts/mod/devicetable-offsets.s] Error 1
   make[2]: Target 'scripts/mod/' not remade because of errors.
   make[1]: *** [Makefile:1269: prepare0] Error 2
   make[1]: Target 'prepare' not remade because of errors.
   make: *** [Makefile:231: __sub-make] Error 2
   make: Target 'prepare' not remade because of errors.


vim +/static_key_initialized +32 arch/powerpc/include/asm/cpu_has_feature.h

4db7327194dba0 Kevin Hao        2016-07-23  20  
4db7327194dba0 Kevin Hao        2016-07-23 @21  extern struct static_key_true cpu_feature_keys[NUM_CPU_FTR_KEYS];
4db7327194dba0 Kevin Hao        2016-07-23  22  
4db7327194dba0 Kevin Hao        2016-07-23  23  static __always_inline bool cpu_has_feature(unsigned long feature)
4db7327194dba0 Kevin Hao        2016-07-23  24  {
4db7327194dba0 Kevin Hao        2016-07-23 @25  	int i;
4db7327194dba0 Kevin Hao        2016-07-23  26  
b5fa0f7f88edcd Michael Ellerman 2017-01-24  27  #ifndef __clang__ /* clang can't cope with this */
4db7327194dba0 Kevin Hao        2016-07-23  28  	BUILD_BUG_ON(!__builtin_constant_p(feature));
b5fa0f7f88edcd Michael Ellerman 2017-01-24  29  #endif
4db7327194dba0 Kevin Hao        2016-07-23  30  
c812c7d8f1470a Aneesh Kumar K.V 2016-07-23  31  #ifdef CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG
c812c7d8f1470a Aneesh Kumar K.V 2016-07-23 @32  	if (!static_key_initialized) {
c812c7d8f1470a Aneesh Kumar K.V 2016-07-23  33  		printk("Warning! cpu_has_feature() used prior to jump label init!\n");
c812c7d8f1470a Aneesh Kumar K.V 2016-07-23  34  		dump_stack();
c812c7d8f1470a Aneesh Kumar K.V 2016-07-23  35  		return early_cpu_has_feature(feature);
c812c7d8f1470a Aneesh Kumar K.V 2016-07-23  36  	}
c812c7d8f1470a Aneesh Kumar K.V 2016-07-23  37  #endif
c812c7d8f1470a Aneesh Kumar K.V 2016-07-23  38  
4db7327194dba0 Kevin Hao        2016-07-23  39  	if (CPU_FTRS_ALWAYS & feature)
4db7327194dba0 Kevin Hao        2016-07-23  40  		return true;
4db7327194dba0 Kevin Hao        2016-07-23  41  
4db7327194dba0 Kevin Hao        2016-07-23  42  	if (!(CPU_FTRS_POSSIBLE & feature))
4db7327194dba0 Kevin Hao        2016-07-23  43  		return false;
4db7327194dba0 Kevin Hao        2016-07-23  44  
4db7327194dba0 Kevin Hao        2016-07-23  45  	i = __builtin_ctzl(feature);
4db7327194dba0 Kevin Hao        2016-07-23 @46  	return static_branch_likely(&cpu_feature_keys[i]);
4db7327194dba0 Kevin Hao        2016-07-23  47  }
4db7327194dba0 Kevin Hao        2016-07-23  48  #else
eed5fae00593ab Christophe Leroy 2021-03-10  49  static __always_inline bool cpu_has_feature(unsigned long feature)
b92a226e528423 Kevin Hao        2016-07-23  50  {
b92a226e528423 Kevin Hao        2016-07-23  51  	return early_cpu_has_feature(feature);
b92a226e528423 Kevin Hao        2016-07-23  52  }
4db7327194dba0 Kevin Hao        2016-07-23  53  #endif
b92a226e528423 Kevin Hao        2016-07-23  54
  
kernel test robot Nov. 3, 2022, 11:46 p.m. UTC | #3
Hi Dmitry,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on f2f32f8af2b0ca9d619e5183eae3eed431793baf]

url:    https://github.com/intel-lab-lkp/linux/commits/Dmitry-Safonov/net-tcp-Dynamically-disable-TCP-MD5-static-key/20221104-052738
base:   f2f32f8af2b0ca9d619e5183eae3eed431793baf
patch link:    https://lore.kernel.org/r/20221103212524.865762-2-dima%40arista.com
patch subject: [PATCH v2 1/3] jump_label: Add static_key_fast_inc()
config: mips-allyesconfig
compiler: mips-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/bff5ecacd7c0f1e5d610c025726a6c5cb992e828
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Dmitry-Safonov/net-tcp-Dynamically-disable-TCP-MD5-static-key/20221104-052738
        git checkout bff5ecacd7c0f1e5d610c025726a6c5cb992e828
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=mips prepare

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from include/linux/dynamic_debug.h:6,
                    from include/linux/printk.h:566,
                    from include/asm-generic/bug.h:22,
                    from arch/mips/include/asm/bug.h:42,
                    from include/linux/bug.h:5,
                    from include/linux/fortify-string.h:5,
                    from include/linux/string.h:253,
                    from include/linux/uuid.h:12,
                    from include/linux/mod_devicetable.h:13,
                    from scripts/mod/devicetable-offsets.c:3:
   include/linux/jump_label.h: In function 'static_key_fast_inc':
>> include/linux/jump_label.h:83:35: error: implicit declaration of function 'WARN' [-Werror=implicit-function-declaration]
      83 | #define STATIC_KEY_CHECK_USE(key) WARN(!static_key_initialized,               \
         |                                   ^~~~
   include/linux/jump_label.h:250:9: note: in expansion of macro 'STATIC_KEY_CHECK_USE'
     250 |         STATIC_KEY_CHECK_USE(key);
         |         ^~~~~~~~~~~~~~~~~~~~
>> include/linux/jump_label.h:251:9: error: implicit declaration of function 'WARN_ON_ONCE' [-Werror=implicit-function-declaration]
     251 |         WARN_ON_ONCE(atomic_read(&key->enabled) < 1);
         |         ^~~~~~~~~~~~
   cc1: some warnings being treated as errors
   make[2]: *** [scripts/Makefile.build:118: scripts/mod/devicetable-offsets.s] Error 1
   make[2]: Target 'scripts/mod/' not remade because of errors.
   make[1]: *** [Makefile:1269: prepare0] Error 2
   make[1]: Target 'prepare' not remade because of errors.
   make: *** [Makefile:231: __sub-make] Error 2
   make: Target 'prepare' not remade because of errors.


vim +/WARN +83 include/linux/jump_label.h

c4b2c0c5f647aa Hannes Frederic Sowa       2013-10-19   82  
5cdda5117e125e Borislav Petkov            2017-10-18  @83  #define STATIC_KEY_CHECK_USE(key) WARN(!static_key_initialized,		      \
5cdda5117e125e Borislav Petkov            2017-10-18   84  				    "%s(): static key '%pS' used before call to jump_label_init()", \
5cdda5117e125e Borislav Petkov            2017-10-18   85  				    __func__, (key))
d430d3d7e646eb Jason Baron                2011-03-16   86  
c5905afb0ee655 Ingo Molnar                2012-02-24   87  struct static_key {
d430d3d7e646eb Jason Baron                2011-03-16   88  	atomic_t enabled;
cd27ccfc727e99 Masahiro Yamada            2022-02-14   89  #ifdef CONFIG_JUMP_LABEL
3821fd35b58dba Jason Baron                2017-02-03   90  /*
b17ef2ed624aa7 Steven Rostedt (VMware     2017-03-02   91)  * Note:
b17ef2ed624aa7 Steven Rostedt (VMware     2017-03-02   92)  *   To make anonymous unions work with old compilers, the static
b17ef2ed624aa7 Steven Rostedt (VMware     2017-03-02   93)  *   initialization of them requires brackets. This creates a dependency
b17ef2ed624aa7 Steven Rostedt (VMware     2017-03-02   94)  *   on the order of the struct with the initializers. If any fields
b17ef2ed624aa7 Steven Rostedt (VMware     2017-03-02   95)  *   are added, STATIC_KEY_INIT_TRUE and STATIC_KEY_INIT_FALSE may need
b17ef2ed624aa7 Steven Rostedt (VMware     2017-03-02   96)  *   to be modified.
b17ef2ed624aa7 Steven Rostedt (VMware     2017-03-02   97)  *
3821fd35b58dba Jason Baron                2017-02-03   98   * bit 0 => 1 if key is initially true
3821fd35b58dba Jason Baron                2017-02-03   99   *	    0 if initially false
3821fd35b58dba Jason Baron                2017-02-03  100   * bit 1 => 1 if points to struct static_key_mod
3821fd35b58dba Jason Baron                2017-02-03  101   *	    0 if points to struct jump_entry
3821fd35b58dba Jason Baron                2017-02-03  102   */
3821fd35b58dba Jason Baron                2017-02-03  103  	union {
3821fd35b58dba Jason Baron                2017-02-03  104  		unsigned long type;
d430d3d7e646eb Jason Baron                2011-03-16  105  		struct jump_entry *entries;
c5905afb0ee655 Ingo Molnar                2012-02-24  106  		struct static_key_mod *next;
3821fd35b58dba Jason Baron                2017-02-03  107  	};
cd27ccfc727e99 Masahiro Yamada            2022-02-14  108  #endif	/* CONFIG_JUMP_LABEL */
d430d3d7e646eb Jason Baron                2011-03-16  109  };
d430d3d7e646eb Jason Baron                2011-03-16  110  
c0ccf6f99e3a43 Anton Blanchard            2015-04-09  111  #endif /* __ASSEMBLY__ */
c0ccf6f99e3a43 Anton Blanchard            2015-04-09  112  
e9666d10a5677a Masahiro Yamada            2018-12-31  113  #ifdef CONFIG_JUMP_LABEL
c0ccf6f99e3a43 Anton Blanchard            2015-04-09  114  #include <asm/jump_label.h>
9ae033aca8d600 Ard Biesheuvel             2018-09-18  115  
9ae033aca8d600 Ard Biesheuvel             2018-09-18  116  #ifndef __ASSEMBLY__
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  117  #ifdef CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  118  
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  119  struct jump_entry {
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  120  	s32 code;
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  121  	s32 target;
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  122  	long key;	// key may be far away from the core kernel under KASLR
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  123  };
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  124  
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  125  static inline unsigned long jump_entry_code(const struct jump_entry *entry)
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  126  {
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  127  	return (unsigned long)&entry->code + entry->code;
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  128  }
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  129  
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  130  static inline unsigned long jump_entry_target(const struct jump_entry *entry)
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  131  {
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  132  	return (unsigned long)&entry->target + entry->target;
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  133  }
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  134  
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  135  static inline struct static_key *jump_entry_key(const struct jump_entry *entry)
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  136  {
19483677684b6c Ard Biesheuvel             2018-09-18  137  	long offset = entry->key & ~3L;
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  138  
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  139  	return (struct static_key *)((unsigned long)&entry->key + offset);
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  140  }
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  141  
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  142  #else
9ae033aca8d600 Ard Biesheuvel             2018-09-18  143  
9ae033aca8d600 Ard Biesheuvel             2018-09-18  144  static inline unsigned long jump_entry_code(const struct jump_entry *entry)
9ae033aca8d600 Ard Biesheuvel             2018-09-18  145  {
9ae033aca8d600 Ard Biesheuvel             2018-09-18  146  	return entry->code;
9ae033aca8d600 Ard Biesheuvel             2018-09-18  147  }
9ae033aca8d600 Ard Biesheuvel             2018-09-18  148  
9ae033aca8d600 Ard Biesheuvel             2018-09-18  149  static inline unsigned long jump_entry_target(const struct jump_entry *entry)
9ae033aca8d600 Ard Biesheuvel             2018-09-18  150  {
9ae033aca8d600 Ard Biesheuvel             2018-09-18  151  	return entry->target;
9ae033aca8d600 Ard Biesheuvel             2018-09-18  152  }
9ae033aca8d600 Ard Biesheuvel             2018-09-18  153  
9ae033aca8d600 Ard Biesheuvel             2018-09-18  154  static inline struct static_key *jump_entry_key(const struct jump_entry *entry)
9ae033aca8d600 Ard Biesheuvel             2018-09-18  155  {
19483677684b6c Ard Biesheuvel             2018-09-18  156  	return (struct static_key *)((unsigned long)entry->key & ~3UL);
9ae033aca8d600 Ard Biesheuvel             2018-09-18  157  }
9ae033aca8d600 Ard Biesheuvel             2018-09-18  158  
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  159  #endif
50ff18ab497aa2 Ard Biesheuvel             2018-09-18  160  
9ae033aca8d600 Ard Biesheuvel             2018-09-18  161  static inline bool jump_entry_is_branch(const struct jump_entry *entry)
9ae033aca8d600 Ard Biesheuvel             2018-09-18  162  {
9ae033aca8d600 Ard Biesheuvel             2018-09-18  163  	return (unsigned long)entry->key & 1UL;
9ae033aca8d600 Ard Biesheuvel             2018-09-18  164  }
9ae033aca8d600 Ard Biesheuvel             2018-09-18  165  
9ae033aca8d600 Ard Biesheuvel             2018-09-18  166  static inline bool jump_entry_is_init(const struct jump_entry *entry)
9ae033aca8d600 Ard Biesheuvel             2018-09-18  167  {
19483677684b6c Ard Biesheuvel             2018-09-18  168  	return (unsigned long)entry->key & 2UL;
9ae033aca8d600 Ard Biesheuvel             2018-09-18  169  }
9ae033aca8d600 Ard Biesheuvel             2018-09-18  170  
5af0ea293d78c8 Peter Zijlstra             2021-05-06  171  static inline void jump_entry_set_init(struct jump_entry *entry, bool set)
9ae033aca8d600 Ard Biesheuvel             2018-09-18  172  {
5af0ea293d78c8 Peter Zijlstra             2021-05-06  173  	if (set)
19483677684b6c Ard Biesheuvel             2018-09-18  174  		entry->key |= 2;
5af0ea293d78c8 Peter Zijlstra             2021-05-06  175  	else
5af0ea293d78c8 Peter Zijlstra             2021-05-06  176  		entry->key &= ~2;
9ae033aca8d600 Ard Biesheuvel             2018-09-18  177  }
9ae033aca8d600 Ard Biesheuvel             2018-09-18  178  
fa5e5dc39669b4 Peter Zijlstra             2021-05-06  179  static inline int jump_entry_size(struct jump_entry *entry)
fa5e5dc39669b4 Peter Zijlstra             2021-05-06  180  {
fa5e5dc39669b4 Peter Zijlstra             2021-05-06  181  #ifdef JUMP_LABEL_NOP_SIZE
fa5e5dc39669b4 Peter Zijlstra             2021-05-06  182  	return JUMP_LABEL_NOP_SIZE;
fa5e5dc39669b4 Peter Zijlstra             2021-05-06  183  #else
fa5e5dc39669b4 Peter Zijlstra             2021-05-06  184  	return arch_jump_entry_size(entry);
fa5e5dc39669b4 Peter Zijlstra             2021-05-06  185  #endif
fa5e5dc39669b4 Peter Zijlstra             2021-05-06  186  }
fa5e5dc39669b4 Peter Zijlstra             2021-05-06  187  
9ae033aca8d600 Ard Biesheuvel             2018-09-18  188  #endif
c0ccf6f99e3a43 Anton Blanchard            2015-04-09  189  #endif
c0ccf6f99e3a43 Anton Blanchard            2015-04-09  190  
c0ccf6f99e3a43 Anton Blanchard            2015-04-09  191  #ifndef __ASSEMBLY__
bf5438fca2950b Jason Baron                2010-09-17  192  
bf5438fca2950b Jason Baron                2010-09-17  193  enum jump_label_type {
76b235c6bcb160 Peter Zijlstra             2015-07-24  194  	JUMP_LABEL_NOP = 0,
76b235c6bcb160 Peter Zijlstra             2015-07-24  195  	JUMP_LABEL_JMP,
bf5438fca2950b Jason Baron                2010-09-17  196  };
bf5438fca2950b Jason Baron                2010-09-17  197  
bf5438fca2950b Jason Baron                2010-09-17  198  struct module;
bf5438fca2950b Jason Baron                2010-09-17  199  
e9666d10a5677a Masahiro Yamada            2018-12-31  200  #ifdef CONFIG_JUMP_LABEL
4c5ea0a9cd02d6 Paolo Bonzini              2016-06-21  201  
a1efb01feca597 Peter Zijlstra             2015-07-24  202  #define JUMP_TYPE_FALSE		0UL
a1efb01feca597 Peter Zijlstra             2015-07-24  203  #define JUMP_TYPE_TRUE		1UL
3821fd35b58dba Jason Baron                2017-02-03  204  #define JUMP_TYPE_LINKED	2UL
3821fd35b58dba Jason Baron                2017-02-03  205  #define JUMP_TYPE_MASK		3UL
c5905afb0ee655 Ingo Molnar                2012-02-24  206  
c5905afb0ee655 Ingo Molnar                2012-02-24  207  static __always_inline bool static_key_false(struct static_key *key)
c5905afb0ee655 Ingo Molnar                2012-02-24  208  {
11276d5306b8e5 Peter Zijlstra             2015-07-24  209  	return arch_static_branch(key, false);
c5905afb0ee655 Ingo Molnar                2012-02-24  210  }
d430d3d7e646eb Jason Baron                2011-03-16  211  
c5905afb0ee655 Ingo Molnar                2012-02-24  212  static __always_inline bool static_key_true(struct static_key *key)
c5905afb0ee655 Ingo Molnar                2012-02-24  213  {
11276d5306b8e5 Peter Zijlstra             2015-07-24  214  	return !arch_static_branch(key, true);
c5905afb0ee655 Ingo Molnar                2012-02-24  215  }
c5905afb0ee655 Ingo Molnar                2012-02-24  216  
bf5438fca2950b Jason Baron                2010-09-17  217  extern struct jump_entry __start___jump_table[];
bf5438fca2950b Jason Baron                2010-09-17  218  extern struct jump_entry __stop___jump_table[];
bf5438fca2950b Jason Baron                2010-09-17  219  
97ce2c88f9ad42 Jeremy Fitzhardinge        2011-10-12  220  extern void jump_label_init(void);
91bad2f8d30574 Jason Baron                2010-10-01  221  extern void jump_label_lock(void);
91bad2f8d30574 Jason Baron                2010-10-01  222  extern void jump_label_unlock(void);
bf5438fca2950b Jason Baron                2010-09-17  223  extern void arch_jump_label_transform(struct jump_entry *entry,
bf5438fca2950b Jason Baron                2010-09-17  224  				      enum jump_label_type type);
c2ba8a15f310d9 Daniel Bristot de Oliveira 2019-06-12  225  extern bool arch_jump_label_transform_queue(struct jump_entry *entry,
c2ba8a15f310d9 Daniel Bristot de Oliveira 2019-06-12  226  					    enum jump_label_type type);
c2ba8a15f310d9 Daniel Bristot de Oliveira 2019-06-12  227  extern void arch_jump_label_transform_apply(void);
4c3ef6d79328c0 Jason Baron                2010-09-17  228  extern int jump_label_text_reserved(void *start, void *end);
c5905afb0ee655 Ingo Molnar                2012-02-24  229  extern void static_key_slow_inc(struct static_key *key);
c5905afb0ee655 Ingo Molnar                2012-02-24  230  extern void static_key_slow_dec(struct static_key *key);
ce48c146495a1a Peter Zijlstra             2018-01-22  231  extern void static_key_slow_inc_cpuslocked(struct static_key *key);
ce48c146495a1a Peter Zijlstra             2018-01-22  232  extern void static_key_slow_dec_cpuslocked(struct static_key *key);
1f69bf9c613760 Jason Baron                2016-08-03  233  extern int static_key_count(struct static_key *key);
1f69bf9c613760 Jason Baron                2016-08-03  234  extern void static_key_enable(struct static_key *key);
1f69bf9c613760 Jason Baron                2016-08-03  235  extern void static_key_disable(struct static_key *key);
5a40527f8f0798 Marc Zyngier               2017-08-01  236  extern void static_key_enable_cpuslocked(struct static_key *key);
5a40527f8f0798 Marc Zyngier               2017-08-01  237  extern void static_key_disable_cpuslocked(struct static_key *key);
fdfd42892f311e Ard Biesheuvel             2022-06-15  238  extern enum jump_label_type jump_label_init_type(struct jump_entry *entry);
c5905afb0ee655 Ingo Molnar                2012-02-24  239  
bff5ecacd7c0f1 Dmitry Safonov             2022-11-03  240  /***
bff5ecacd7c0f1 Dmitry Safonov             2022-11-03  241   * static_key_fast_inc - adds a user for a static key
bff5ecacd7c0f1 Dmitry Safonov             2022-11-03  242   * @key: static key that must be already enabled
bff5ecacd7c0f1 Dmitry Safonov             2022-11-03  243   *
bff5ecacd7c0f1 Dmitry Safonov             2022-11-03  244   * The caller must make sure that the static key can't get disabled while
bff5ecacd7c0f1 Dmitry Safonov             2022-11-03  245   * in this function. It doesn't patch jump labels, only adds a user to
bff5ecacd7c0f1 Dmitry Safonov             2022-11-03  246   * an already enabled static key.
bff5ecacd7c0f1 Dmitry Safonov             2022-11-03  247   */
bff5ecacd7c0f1 Dmitry Safonov             2022-11-03  248  static inline void static_key_fast_inc(struct static_key *key)
bff5ecacd7c0f1 Dmitry Safonov             2022-11-03  249  {
bff5ecacd7c0f1 Dmitry Safonov             2022-11-03  250  	STATIC_KEY_CHECK_USE(key);
bff5ecacd7c0f1 Dmitry Safonov             2022-11-03 @251  	WARN_ON_ONCE(atomic_read(&key->enabled) < 1);
bff5ecacd7c0f1 Dmitry Safonov             2022-11-03  252  	atomic_inc(&key->enabled);
bff5ecacd7c0f1 Dmitry Safonov             2022-11-03  253  }
bff5ecacd7c0f1 Dmitry Safonov             2022-11-03  254
  
Dmitry Safonov Nov. 4, 2022, 4:27 p.m. UTC | #4
On 11/3/22 21:41, Peter Zijlstra wrote:
> On Thu, Nov 03, 2022 at 09:25:22PM +0000, Dmitry Safonov wrote:
>> A helper to add another user for an existing enabled static key.
> 
> Utter lack of clue what for.
> 
>> +/***
>> + * static_key_fast_inc - adds a user for a static key
>> + * @key: static key that must be already enabled
>> + *
>> + * The caller must make sure that the static key can't get disabled while
>> + * in this function. It doesn't patch jump labels, only adds a user to
>> + * an already enabled static key.
>> + */
>> +static inline void static_key_fast_inc(struct static_key *key)
>> +{
>> +	STATIC_KEY_CHECK_USE(key);
>> +	WARN_ON_ONCE(atomic_read(&key->enabled) < 1);
>> +	atomic_inc(&key->enabled);
>> +}
> 
> And no, that's racy as heck. We have things like atomic_inc_not_zero(),
> I suggest looking into it.

Thanks for the review, I'll look into that for v3.

Thanks,
          Dmitry
  

Patch

diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h
index 570831ca9951..cb6c722c4816 100644
--- a/include/linux/jump_label.h
+++ b/include/linux/jump_label.h
@@ -75,6 +75,8 @@ 
 
 #include <linux/types.h>
 #include <linux/compiler.h>
+#include <linux/atomic.h>
+#include <linux/bug.h>
 
 extern bool static_key_initialized;
 
@@ -235,6 +237,21 @@  extern void static_key_enable_cpuslocked(struct static_key *key);
 extern void static_key_disable_cpuslocked(struct static_key *key);
 extern enum jump_label_type jump_label_init_type(struct jump_entry *entry);
 
+/***
+ * static_key_fast_inc - adds a user for a static key
+ * @key: static key that must be already enabled
+ *
+ * The caller must make sure that the static key can't get disabled while
+ * in this function. It doesn't patch jump labels, only adds a user to
+ * an already enabled static key.
+ */
+static inline void static_key_fast_inc(struct static_key *key)
+{
+	STATIC_KEY_CHECK_USE(key);
+	WARN_ON_ONCE(atomic_read(&key->enabled) < 1);
+	atomic_inc(&key->enabled);
+}
+
 /*
  * We should be using ATOMIC_INIT() for initializing .enabled, but
  * the inclusion of atomic.h is problematic for inclusion of jump_label.h
@@ -251,9 +268,6 @@  extern enum jump_label_type jump_label_init_type(struct jump_entry *entry);
 
 #else  /* !CONFIG_JUMP_LABEL */
 
-#include <linux/atomic.h>
-#include <linux/bug.h>
-
 static __always_inline int static_key_count(struct static_key *key)
 {
 	return arch_atomic_read(&key->enabled);
@@ -290,6 +304,7 @@  static inline void static_key_slow_dec(struct static_key *key)
 	atomic_dec(&key->enabled);
 }
 
+#define static_key_fast_inc(key) static_key_slow_inc(key)
 #define static_key_slow_inc_cpuslocked(key) static_key_slow_inc(key)
 #define static_key_slow_dec_cpuslocked(key) static_key_slow_dec(key)