1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _LINUX_JUMP_LABEL_RATELIMIT_H |
3 | #define _LINUX_JUMP_LABEL_RATELIMIT_H |
4 | |
5 | #include <linux/jump_label.h> |
6 | #include <linux/workqueue.h> |
7 | |
8 | #if defined(CONFIG_JUMP_LABEL) |
9 | struct static_key_deferred { |
10 | struct static_key key; |
11 | unsigned long timeout; |
12 | struct delayed_work work; |
13 | }; |
14 | |
15 | struct static_key_true_deferred { |
16 | struct static_key_true key; |
17 | unsigned long timeout; |
18 | struct delayed_work work; |
19 | }; |
20 | |
21 | struct static_key_false_deferred { |
22 | struct static_key_false key; |
23 | unsigned long timeout; |
24 | struct delayed_work work; |
25 | }; |
26 | |
27 | #define static_key_slow_dec_deferred(x) \ |
28 | __static_key_slow_dec_deferred(&(x)->key, &(x)->work, (x)->timeout) |
29 | #define static_branch_slow_dec_deferred(x) \ |
30 | __static_key_slow_dec_deferred(&(x)->key.key, &(x)->work, (x)->timeout) |
31 | |
32 | #define static_key_deferred_flush(x) \ |
33 | __static_key_deferred_flush((x), &(x)->work) |
34 | |
35 | extern void |
36 | __static_key_slow_dec_deferred(struct static_key *key, |
37 | struct delayed_work *work, |
38 | unsigned long timeout); |
39 | extern void __static_key_deferred_flush(void *key, struct delayed_work *work); |
40 | extern void |
41 | jump_label_rate_limit(struct static_key_deferred *key, unsigned long rl); |
42 | |
43 | extern void jump_label_update_timeout(struct work_struct *work); |
44 | |
45 | #define DEFINE_STATIC_KEY_DEFERRED_TRUE(name, rl) \ |
46 | struct static_key_true_deferred name = { \ |
47 | .key = { STATIC_KEY_INIT_TRUE }, \ |
48 | .timeout = (rl), \ |
49 | .work = __DELAYED_WORK_INITIALIZER((name).work, \ |
50 | jump_label_update_timeout, \ |
51 | 0), \ |
52 | } |
53 | |
54 | #define DEFINE_STATIC_KEY_DEFERRED_FALSE(name, rl) \ |
55 | struct static_key_false_deferred name = { \ |
56 | .key = { STATIC_KEY_INIT_FALSE }, \ |
57 | .timeout = (rl), \ |
58 | .work = __DELAYED_WORK_INITIALIZER((name).work, \ |
59 | jump_label_update_timeout, \ |
60 | 0), \ |
61 | } |
62 | |
63 | #else /* !CONFIG_JUMP_LABEL */ |
64 | struct static_key_deferred { |
65 | struct static_key key; |
66 | }; |
67 | struct static_key_true_deferred { |
68 | struct static_key_true key; |
69 | }; |
70 | struct static_key_false_deferred { |
71 | struct static_key_false key; |
72 | }; |
73 | #define DEFINE_STATIC_KEY_DEFERRED_TRUE(name, rl) \ |
74 | struct static_key_true_deferred name = { STATIC_KEY_TRUE_INIT } |
75 | #define DEFINE_STATIC_KEY_DEFERRED_FALSE(name, rl) \ |
76 | struct static_key_false_deferred name = { STATIC_KEY_FALSE_INIT } |
77 | |
78 | #define static_branch_slow_dec_deferred(x) static_branch_dec(&(x)->key) |
79 | |
80 | static inline void static_key_slow_dec_deferred(struct static_key_deferred *key) |
81 | { |
82 | STATIC_KEY_CHECK_USE(key); |
83 | static_key_slow_dec(&key->key); |
84 | } |
85 | static inline void static_key_deferred_flush(void *key) |
86 | { |
87 | STATIC_KEY_CHECK_USE(key); |
88 | } |
89 | static inline void |
90 | jump_label_rate_limit(struct static_key_deferred *key, |
91 | unsigned long rl) |
92 | { |
93 | STATIC_KEY_CHECK_USE(key); |
94 | } |
95 | #endif /* CONFIG_JUMP_LABEL */ |
96 | |
97 | #define static_branch_deferred_inc(x) static_branch_inc(&(x)->key) |
98 | |
99 | #endif /* _LINUX_JUMP_LABEL_RATELIMIT_H */ |
100 | |