blob: 5ce8b140428f90b4861d2d1ac100cf9d58dac198 [file] [log] [blame]
Jason Baronbf5438fc2010-09-17 11:09:00 -04001#ifndef _LINUX_JUMP_LABEL_H
2#define _LINUX_JUMP_LABEL_H
3
Jason Barond430d3d2011-03-16 17:29:47 -04004#include <linux/types.h>
5#include <linux/compiler.h>
Gleb Natapovb2029522011-11-27 17:59:09 +02006#include <linux/workqueue.h>
Jason Barond430d3d2011-03-16 17:29:47 -04007
Steven Rostedt45f81b12010-10-29 12:33:43 -04008#if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_JUMP_LABEL)
Jason Barond430d3d2011-03-16 17:29:47 -04009
10struct jump_label_key {
11 atomic_t enabled;
12 struct jump_entry *entries;
13#ifdef CONFIG_MODULES
14 struct jump_label_mod *next;
15#endif
16};
17
Gleb Natapovb2029522011-11-27 17:59:09 +020018struct jump_label_key_deferred {
19 struct jump_label_key key;
20 unsigned long timeout;
21 struct delayed_work work;
22};
23
Jason Baronbf5438fc2010-09-17 11:09:00 -040024# include <asm/jump_label.h>
25# define HAVE_JUMP_LABEL
Jeremy Fitzhardinge97ce2c82011-10-12 16:17:54 -070026#endif /* CC_HAVE_ASM_GOTO && CONFIG_JUMP_LABEL */
Jason Baronbf5438fc2010-09-17 11:09:00 -040027
28enum jump_label_type {
Jason Barond430d3d2011-03-16 17:29:47 -040029 JUMP_LABEL_DISABLE = 0,
Jason Baronbf5438fc2010-09-17 11:09:00 -040030 JUMP_LABEL_ENABLE,
Jason Baronbf5438fc2010-09-17 11:09:00 -040031};
32
33struct module;
34
35#ifdef HAVE_JUMP_LABEL
36
Jason Barond430d3d2011-03-16 17:29:47 -040037#ifdef CONFIG_MODULES
Jeremy Fitzhardinged5d9a3b2011-09-28 17:45:15 -070038#define JUMP_LABEL_INIT {ATOMIC_INIT(0), NULL, NULL}
Jason Barond430d3d2011-03-16 17:29:47 -040039#else
Jeremy Fitzhardinged5d9a3b2011-09-28 17:45:15 -070040#define JUMP_LABEL_INIT {ATOMIC_INIT(0), NULL}
Jason Barond430d3d2011-03-16 17:29:47 -040041#endif
42
43static __always_inline bool static_branch(struct jump_label_key *key)
44{
45 return arch_static_branch(key);
46}
47
Jason Baronbf5438fc2010-09-17 11:09:00 -040048extern struct jump_entry __start___jump_table[];
49extern struct jump_entry __stop___jump_table[];
50
Jeremy Fitzhardinge97ce2c82011-10-12 16:17:54 -070051extern void jump_label_init(void);
Jason Baron91bad2f2010-10-01 17:23:48 -040052extern void jump_label_lock(void);
53extern void jump_label_unlock(void);
Jason Baronbf5438fc2010-09-17 11:09:00 -040054extern void arch_jump_label_transform(struct jump_entry *entry,
Jeremy Fitzhardinge37348802011-09-29 11:10:05 -070055 enum jump_label_type type);
Jeremy Fitzhardinge20284aa2011-10-03 11:01:46 -070056extern void arch_jump_label_transform_static(struct jump_entry *entry,
57 enum jump_label_type type);
Jason Baron4c3ef6d2010-09-17 11:09:08 -040058extern int jump_label_text_reserved(void *start, void *end);
Jason Barond430d3d2011-03-16 17:29:47 -040059extern void jump_label_inc(struct jump_label_key *key);
60extern void jump_label_dec(struct jump_label_key *key);
Gleb Natapovb2029522011-11-27 17:59:09 +020061extern void jump_label_dec_deferred(struct jump_label_key_deferred *key);
Jason Barond430d3d2011-03-16 17:29:47 -040062extern bool jump_label_enabled(struct jump_label_key *key);
63extern void jump_label_apply_nops(struct module *mod);
Gleb Natapovb2029522011-11-27 17:59:09 +020064extern void jump_label_rate_limit(struct jump_label_key_deferred *key,
65 unsigned long rl);
Jason Baronbf5438fc2010-09-17 11:09:00 -040066
Jeremy Fitzhardinge97ce2c82011-10-12 16:17:54 -070067#else /* !HAVE_JUMP_LABEL */
Jason Baronbf5438fc2010-09-17 11:09:00 -040068
Arun Sharma600634972011-07-26 16:09:06 -070069#include <linux/atomic.h>
Jason Baronbf5438fc2010-09-17 11:09:00 -040070
Jason Barond430d3d2011-03-16 17:29:47 -040071#define JUMP_LABEL_INIT {ATOMIC_INIT(0)}
Jason Baronbf5438fc2010-09-17 11:09:00 -040072
Jason Barond430d3d2011-03-16 17:29:47 -040073struct jump_label_key {
74 atomic_t enabled;
75};
Jason Baronbf5438fc2010-09-17 11:09:00 -040076
Jeremy Fitzhardinge97ce2c82011-10-12 16:17:54 -070077static __always_inline void jump_label_init(void)
78{
79}
80
Gleb Natapovb2029522011-11-27 17:59:09 +020081struct jump_label_key_deferred {
82 struct jump_label_key key;
83};
84
Jason Barond430d3d2011-03-16 17:29:47 -040085static __always_inline bool static_branch(struct jump_label_key *key)
Jason Baronbf5438fc2010-09-17 11:09:00 -040086{
Jason Barond430d3d2011-03-16 17:29:47 -040087 if (unlikely(atomic_read(&key->enabled)))
88 return true;
89 return false;
90}
91
92static inline void jump_label_inc(struct jump_label_key *key)
93{
94 atomic_inc(&key->enabled);
95}
96
97static inline void jump_label_dec(struct jump_label_key *key)
98{
99 atomic_dec(&key->enabled);
Jason Baronbf5438fc2010-09-17 11:09:00 -0400100}
101
Gleb Natapovb2029522011-11-27 17:59:09 +0200102static inline void jump_label_dec_deferred(struct jump_label_key_deferred *key)
103{
104 jump_label_dec(&key->key);
105}
106
Jason Baron4c3ef6d2010-09-17 11:09:08 -0400107static inline int jump_label_text_reserved(void *start, void *end)
108{
109 return 0;
110}
111
Jason Baron91bad2f2010-10-01 17:23:48 -0400112static inline void jump_label_lock(void) {}
113static inline void jump_label_unlock(void) {}
114
Jason Barond430d3d2011-03-16 17:29:47 -0400115static inline bool jump_label_enabled(struct jump_label_key *key)
116{
117 return !!atomic_read(&key->enabled);
118}
Jason Baronbf5438fc2010-09-17 11:09:00 -0400119
Jason Barond430d3d2011-03-16 17:29:47 -0400120static inline int jump_label_apply_nops(struct module *mod)
121{
122 return 0;
123}
Gleb Natapovb2029522011-11-27 17:59:09 +0200124
125static inline void jump_label_rate_limit(struct jump_label_key_deferred *key,
126 unsigned long rl)
127{
128}
Jeremy Fitzhardinge97ce2c82011-10-12 16:17:54 -0700129#endif /* HAVE_JUMP_LABEL */
Jason Barond430d3d2011-03-16 17:29:47 -0400130
Peter Zijlstraac99b862011-07-06 14:20:14 +0200131#define jump_label_key_enabled ((struct jump_label_key){ .enabled = ATOMIC_INIT(1), })
132#define jump_label_key_disabled ((struct jump_label_key){ .enabled = ATOMIC_INIT(0), })
133
Jeremy Fitzhardinge97ce2c82011-10-12 16:17:54 -0700134#endif /* _LINUX_JUMP_LABEL_H */