2#ifndef _LINUX_JUMP_LABEL_H
3#define _LINUX_JUMP_LABEL_H
82#define STATIC_KEY_CHECK_USE(key) WARN(!static_key_initialized, \
83 "%s(): static key '%pS' used before call to jump_label_init()", \
88#ifdef CONFIG_JUMP_LABEL
97 struct jump_entry *entries;
98 struct static_key_mod *next;
105#ifdef CONFIG_JUMP_LABEL
106#include <asm/jump_label.h>
109#ifdef CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE
117static inline unsigned long jump_entry_code(
const struct jump_entry *
entry)
119 return (
unsigned long)&
entry->code +
entry->code;
122static inline unsigned long jump_entry_target(
const struct jump_entry *
entry)
124 return (
unsigned long)&
entry->target +
entry->target;
127static inline struct static_key *jump_entry_key(
const struct jump_entry *
entry)
136static inline unsigned long jump_entry_code(
const struct jump_entry *
entry)
141static inline unsigned long jump_entry_target(
const struct jump_entry *
entry)
143 return entry->target;
146static inline struct static_key *jump_entry_key(
const struct jump_entry *
entry)
153static inline bool jump_entry_is_branch(
const struct jump_entry *
entry)
155 return (
unsigned long)
entry->key & 1UL;
158static inline bool jump_entry_is_init(
const struct jump_entry *
entry)
160 return (
unsigned long)
entry->key & 2UL;
163static inline void jump_entry_set_init(
struct jump_entry *
entry,
bool set)
171static inline int jump_entry_size(
struct jump_entry *
entry)
173#ifdef JUMP_LABEL_NOP_SIZE
174 return JUMP_LABEL_NOP_SIZE;
176 return arch_jump_entry_size(
entry);
192#ifdef CONFIG_JUMP_LABEL
194#define JUMP_TYPE_FALSE 0UL
195#define JUMP_TYPE_TRUE 1UL
196#define JUMP_TYPE_LINKED 2UL
197#define JUMP_TYPE_MASK 3UL
201 return arch_static_branch(key,
false);
206 return !arch_static_branch(key,
true);
209extern struct jump_entry __start___jump_table[];
210extern struct jump_entry __stop___jump_table[];
212extern void jump_label_init(
void);
213extern void jump_label_init_ro(
void);
214extern void jump_label_lock(
void);
215extern void jump_label_unlock(
void);
216extern void arch_jump_label_transform(
struct jump_entry *
entry,
218extern bool arch_jump_label_transform_queue(
struct jump_entry *
entry,
220extern void arch_jump_label_transform_apply(
void);
221extern int jump_label_text_reserved(
void *start,
void *
end);
223extern bool static_key_fast_inc_not_disabled(
struct static_key *key);
224extern void static_key_slow_dec(
struct static_key *key);
227extern int static_key_count(
struct static_key *key);
228extern void static_key_enable(
struct static_key *key);
229extern void static_key_disable(
struct static_key *key);
234#define STATIC_KEY_INIT_TRUE \
235 { .enabled = ATOMIC_INIT(1), \
236 .type = JUMP_TYPE_TRUE }
237#define STATIC_KEY_INIT_FALSE \
238 { .enabled = ATOMIC_INIT(0), \
239 .type = JUMP_TYPE_FALSE }
248 return raw_atomic_read(&key->
enabled);
260 if (unlikely_notrace(static_key_count(key) > 0))
267 if (likely_notrace(static_key_count(key) > 0))
272static inline bool static_key_fast_inc_not_disabled(
struct static_key *key)
281 v = atomic_read(&key->
enabled);
283 if (v < 0 || (v + 1) < 0)
285 }
while (!
likely(atomic_try_cmpxchg(&key->
enabled, &v, v + 1)));
288#define static_key_slow_inc(key) static_key_fast_inc_not_disabled(key)
290static inline void static_key_slow_dec(
struct static_key *key)
296#define static_key_slow_inc_cpuslocked(key) static_key_slow_inc(key)
297#define static_key_slow_dec_cpuslocked(key) static_key_slow_dec(key)
299static inline int jump_label_text_reserved(
void *start,
void *
end)
304static inline void jump_label_lock(
void) {}
305static inline void jump_label_unlock(
void) {}
307static inline void static_key_enable(
struct static_key *key)
311 if (atomic_read(&key->
enabled) != 0) {
318static inline void static_key_disable(
struct static_key *key)
322 if (atomic_read(&key->
enabled) != 1) {
329#define static_key_enable_cpuslocked(k) static_key_enable((k))
330#define static_key_disable_cpuslocked(k) static_key_disable((k))
332#define STATIC_KEY_INIT_TRUE { .enabled = ATOMIC_INIT(1) }
333#define STATIC_KEY_INIT_FALSE { .enabled = ATOMIC_INIT(0) }
339#define STATIC_KEY_INIT STATIC_KEY_INIT_FALSE
340#define jump_label_enabled static_key_enabled
351struct static_key_true {
359#define STATIC_KEY_TRUE_INIT (struct static_key_true) { .key = STATIC_KEY_INIT_TRUE, }
360#define STATIC_KEY_FALSE_INIT (struct static_key_false){ .key = STATIC_KEY_INIT_FALSE, }
362#define DEFINE_STATIC_KEY_TRUE(name) \
363 struct static_key_true name = STATIC_KEY_TRUE_INIT
365#define DEFINE_STATIC_KEY_TRUE_RO(name) \
366 struct static_key_true name __ro_after_init = STATIC_KEY_TRUE_INIT
368#define DECLARE_STATIC_KEY_TRUE(name) \
369 extern struct static_key_true name
371#define DEFINE_STATIC_KEY_FALSE(name) \
372 struct static_key_false name = STATIC_KEY_FALSE_INIT
374#define DEFINE_STATIC_KEY_FALSE_RO(name) \
375 struct static_key_false name __ro_after_init = STATIC_KEY_FALSE_INIT
377#define DECLARE_STATIC_KEY_FALSE(name) \
378 extern struct static_key_false name
380#define DEFINE_STATIC_KEY_ARRAY_TRUE(name, count) \
381 struct static_key_true name[count] = { \
382 [0 ... (count) - 1] = STATIC_KEY_TRUE_INIT, \
385#define DEFINE_STATIC_KEY_ARRAY_FALSE(name, count) \
386 struct static_key_false name[count] = { \
387 [0 ... (count) - 1] = STATIC_KEY_FALSE_INIT, \
390#define _DEFINE_STATIC_KEY_1(name) DEFINE_STATIC_KEY_TRUE(name)
391#define _DEFINE_STATIC_KEY_0(name) DEFINE_STATIC_KEY_FALSE(name)
392#define DEFINE_STATIC_KEY_MAYBE(cfg, name) \
393 __PASTE(_DEFINE_STATIC_KEY_, IS_ENABLED(cfg))(name)
395#define _DEFINE_STATIC_KEY_RO_1(name) DEFINE_STATIC_KEY_TRUE_RO(name)
396#define _DEFINE_STATIC_KEY_RO_0(name) DEFINE_STATIC_KEY_FALSE_RO(name)
397#define DEFINE_STATIC_KEY_MAYBE_RO(cfg, name) \
398 __PASTE(_DEFINE_STATIC_KEY_RO_, IS_ENABLED(cfg))(name)
400#define _DECLARE_STATIC_KEY_1(name) DECLARE_STATIC_KEY_TRUE(name)
401#define _DECLARE_STATIC_KEY_0(name) DECLARE_STATIC_KEY_FALSE(name)
402#define DECLARE_STATIC_KEY_MAYBE(cfg, name) \
403 __PASTE(_DECLARE_STATIC_KEY_, IS_ENABLED(cfg))(name)
407#define static_key_enabled(x) \
409 if (!__builtin_types_compatible_p(typeof(*x), struct static_key) && \
410 !__builtin_types_compatible_p(typeof(*x), struct static_key_true) &&\
411 !__builtin_types_compatible_p(typeof(*x), struct static_key_false)) \
412 ____wrong_branch_error(); \
413 static_key_count((struct static_key *)x) > 0; \
416#ifdef CONFIG_JUMP_LABEL
474#define static_branch_likely(x) \
477 if (__builtin_types_compatible_p(typeof(*x), struct static_key_true)) \
478 branch = !arch_static_branch(&(x)->key, true); \
479 else if (__builtin_types_compatible_p(typeof(*x), struct static_key_false)) \
480 branch = !arch_static_branch_jump(&(x)->key, true); \
482 branch = ____wrong_branch_error(); \
483 likely_notrace(branch); \
486#define static_branch_unlikely(x) \
489 if (__builtin_types_compatible_p(typeof(*x), struct static_key_true)) \
490 branch = arch_static_branch_jump(&(x)->key, false); \
491 else if (__builtin_types_compatible_p(typeof(*x), struct static_key_false)) \
492 branch = arch_static_branch(&(x)->key, false); \
494 branch = ____wrong_branch_error(); \
495 unlikely_notrace(branch); \
500#define static_branch_likely(x) likely_notrace(static_key_enabled(&(x)->key))
501#define static_branch_unlikely(x) unlikely_notrace(static_key_enabled(&(x)->key))
505#define static_branch_maybe(config, x) \
506 (IS_ENABLED(config) ? static_branch_likely(x) \
507 : static_branch_unlikely(x))
513#define static_branch_inc(x) static_key_slow_inc(&(x)->key)
514#define static_branch_dec(x) static_key_slow_dec(&(x)->key)
515#define static_branch_inc_cpuslocked(x) static_key_slow_inc_cpuslocked(&(x)->key)
516#define static_branch_dec_cpuslocked(x) static_key_slow_dec_cpuslocked(&(x)->key)
522#define static_branch_enable(x) static_key_enable(&(x)->key)
523#define static_branch_disable(x) static_key_disable(&(x)->key)
524#define static_branch_enable_cpuslocked(x) static_key_enable_cpuslocked(&(x)->key)
525#define static_branch_disable_cpuslocked(x) static_key_disable_cpuslocked(&(x)->key)
#define DEFINE_LOCK_GUARD_0(_name, _lock, _unlock,...)
Definition cleanup.h:320
#define likely(x)
Definition compiler.h:29
#define __always_inline
Definition compiler_attributes.h:55
size_t size_t offset
Definition drm_bridge.h:1299
bool static_key_initialized
#define static_key_disable_cpuslocked(k)
Definition jump_label.h:330
#define static_key_enable_cpuslocked(k)
Definition jump_label.h:329
#define static_key_slow_inc_cpuslocked(key)
Definition jump_label.h:296
#define static_key_slow_inc(key)
Definition jump_label.h:288
#define static_key_slow_dec_cpuslocked(key)
Definition jump_label.h:297
jump_label_type
Definition jump_label.h:185
@ JUMP_LABEL_NOP
Definition jump_label.h:186
@ JUMP_LABEL_JMP
Definition jump_label.h:187
#define STATIC_KEY_CHECK_USE(key)
Definition jump_label.h:82
bool ____wrong_branch_error(void)
#define WARN_ON_ONCE(cond)
Definition kernel.h:648
int32_t s32
Definition kernel.h:20
void(* entry)(void *)
Definition process.h:101
Definition jump_label.h:355
struct static_key key
Definition jump_label.h:356
Definition jump_label.h:86
atomic_t enabled
Definition jump_label.h:87