diff options
author | Ingo Molnar <mingo@kernel.org> | 2017-06-20 06:19:09 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2017-06-20 06:19:09 -0400 |
commit | 5dd43ce2f69d42a71dcacdb13d17d8c0ac1fe8f7 (patch) | |
tree | 8fd9fc956274bf3b64b4ec736cdb38d9ba9bf6c3 /include/linux/wait_bit.h | |
parent | 4b1c480bfa3b246e292f4d50167756252a9717ed (diff) |
sched/wait: Split out the wait_bit*() APIs from <linux/wait.h> into <linux/wait_bit.h>
The wait_bit*() types and APIs are mixed into wait.h, but they
are a pretty orthogonal extension of wait-queues.
Furthermore, only about 50 kernel files use these APIs, while
over 1000 use the regular wait-queue functionality.
So clean up the main wait.h by moving the wait-bit functionality
out of it, into a separate .h and .c file:
include/linux/wait_bit.h for types and APIs
kernel/sched/wait_bit.c for the implementation
Update all header dependencies.
This reduces the size of wait.h rather significantly, by about 30%.
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'include/linux/wait_bit.h')
-rw-r--r-- | include/linux/wait_bit.h | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/include/linux/wait_bit.h b/include/linux/wait_bit.h new file mode 100644 index 000000000000..8c85c52d94b6 --- /dev/null +++ b/include/linux/wait_bit.h | |||
@@ -0,0 +1,260 @@ | |||
1 | #ifndef _LINUX_WAIT_BIT_H | ||
2 | #define _LINUX_WAIT_BIT_H | ||
3 | |||
4 | /* | ||
5 | * Linux wait-bit related types and methods: | ||
6 | */ | ||
7 | #include <linux/wait.h> | ||
8 | |||
9 | struct wait_bit_key { | ||
10 | void *flags; | ||
11 | int bit_nr; | ||
12 | #define WAIT_ATOMIC_T_BIT_NR -1 | ||
13 | unsigned long timeout; | ||
14 | }; | ||
15 | |||
16 | struct wait_bit_queue_entry { | ||
17 | struct wait_bit_key key; | ||
18 | struct wait_queue_entry wq_entry; | ||
19 | }; | ||
20 | |||
21 | #define __WAIT_BIT_KEY_INITIALIZER(word, bit) \ | ||
22 | { .flags = word, .bit_nr = bit, } | ||
23 | |||
24 | #define __WAIT_ATOMIC_T_KEY_INITIALIZER(p) \ | ||
25 | { .flags = p, .bit_nr = WAIT_ATOMIC_T_BIT_NR, } | ||
26 | |||
27 | typedef int wait_bit_action_f(struct wait_bit_key *key, int mode); | ||
28 | void __wake_up_bit(struct wait_queue_head *wq_head, void *word, int bit); | ||
29 | int __wait_on_bit(struct wait_queue_head *wq_head, struct wait_bit_queue_entry *wbq_entry, wait_bit_action_f *action, unsigned int mode); | ||
30 | int __wait_on_bit_lock(struct wait_queue_head *wq_head, struct wait_bit_queue_entry *wbq_entry, wait_bit_action_f *action, unsigned int mode); | ||
31 | void wake_up_bit(void *word, int bit); | ||
32 | void wake_up_atomic_t(atomic_t *p); | ||
33 | int out_of_line_wait_on_bit(void *word, int, wait_bit_action_f *action, unsigned int mode); | ||
34 | int out_of_line_wait_on_bit_timeout(void *word, int, wait_bit_action_f *action, unsigned int mode, unsigned long timeout); | ||
35 | int out_of_line_wait_on_bit_lock(void *word, int, wait_bit_action_f *action, unsigned int mode); | ||
36 | int out_of_line_wait_on_atomic_t(atomic_t *p, int (*)(atomic_t *), unsigned int mode); | ||
37 | struct wait_queue_head *bit_waitqueue(void *word, int bit); | ||
38 | |||
39 | int wake_bit_function(struct wait_queue_entry *wq_entry, unsigned mode, int sync, void *key); | ||
40 | |||
41 | #define DEFINE_WAIT_BIT(name, word, bit) \ | ||
42 | struct wait_bit_queue_entry name = { \ | ||
43 | .key = __WAIT_BIT_KEY_INITIALIZER(word, bit), \ | ||
44 | .wq_entry = { \ | ||
45 | .private = current, \ | ||
46 | .func = wake_bit_function, \ | ||
47 | .task_list = \ | ||
48 | LIST_HEAD_INIT((name).wq_entry.task_list), \ | ||
49 | }, \ | ||
50 | } | ||
51 | |||
52 | extern int bit_wait(struct wait_bit_key *key, int bit); | ||
53 | extern int bit_wait_io(struct wait_bit_key *key, int bit); | ||
54 | extern int bit_wait_timeout(struct wait_bit_key *key, int bit); | ||
55 | extern int bit_wait_io_timeout(struct wait_bit_key *key, int bit); | ||
56 | |||
57 | /** | ||
58 | * wait_on_bit - wait for a bit to be cleared | ||
59 | * @word: the word being waited on, a kernel virtual address | ||
60 | * @bit: the bit of the word being waited on | ||
61 | * @mode: the task state to sleep in | ||
62 | * | ||
63 | * There is a standard hashed waitqueue table for generic use. This | ||
64 | * is the part of the hashtable's accessor API that waits on a bit. | ||
65 | * For instance, if one were to have waiters on a bitflag, one would | ||
66 | * call wait_on_bit() in threads waiting for the bit to clear. | ||
67 | * One uses wait_on_bit() where one is waiting for the bit to clear, | ||
68 | * but has no intention of setting it. | ||
69 | * Returned value will be zero if the bit was cleared, or non-zero | ||
70 | * if the process received a signal and the mode permitted wakeup | ||
71 | * on that signal. | ||
72 | */ | ||
73 | static inline int | ||
74 | wait_on_bit(unsigned long *word, int bit, unsigned mode) | ||
75 | { | ||
76 | might_sleep(); | ||
77 | if (!test_bit(bit, word)) | ||
78 | return 0; | ||
79 | return out_of_line_wait_on_bit(word, bit, | ||
80 | bit_wait, | ||
81 | mode); | ||
82 | } | ||
83 | |||
84 | /** | ||
85 | * wait_on_bit_io - wait for a bit to be cleared | ||
86 | * @word: the word being waited on, a kernel virtual address | ||
87 | * @bit: the bit of the word being waited on | ||
88 | * @mode: the task state to sleep in | ||
89 | * | ||
90 | * Use the standard hashed waitqueue table to wait for a bit | ||
91 | * to be cleared. This is similar to wait_on_bit(), but calls | ||
92 | * io_schedule() instead of schedule() for the actual waiting. | ||
93 | * | ||
94 | * Returned value will be zero if the bit was cleared, or non-zero | ||
95 | * if the process received a signal and the mode permitted wakeup | ||
96 | * on that signal. | ||
97 | */ | ||
98 | static inline int | ||
99 | wait_on_bit_io(unsigned long *word, int bit, unsigned mode) | ||
100 | { | ||
101 | might_sleep(); | ||
102 | if (!test_bit(bit, word)) | ||
103 | return 0; | ||
104 | return out_of_line_wait_on_bit(word, bit, | ||
105 | bit_wait_io, | ||
106 | mode); | ||
107 | } | ||
108 | |||
109 | /** | ||
110 | * wait_on_bit_timeout - wait for a bit to be cleared or a timeout elapses | ||
111 | * @word: the word being waited on, a kernel virtual address | ||
112 | * @bit: the bit of the word being waited on | ||
113 | * @mode: the task state to sleep in | ||
114 | * @timeout: timeout, in jiffies | ||
115 | * | ||
116 | * Use the standard hashed waitqueue table to wait for a bit | ||
117 | * to be cleared. This is similar to wait_on_bit(), except also takes a | ||
118 | * timeout parameter. | ||
119 | * | ||
120 | * Returned value will be zero if the bit was cleared before the | ||
121 | * @timeout elapsed, or non-zero if the @timeout elapsed or process | ||
122 | * received a signal and the mode permitted wakeup on that signal. | ||
123 | */ | ||
124 | static inline int | ||
125 | wait_on_bit_timeout(unsigned long *word, int bit, unsigned mode, | ||
126 | unsigned long timeout) | ||
127 | { | ||
128 | might_sleep(); | ||
129 | if (!test_bit(bit, word)) | ||
130 | return 0; | ||
131 | return out_of_line_wait_on_bit_timeout(word, bit, | ||
132 | bit_wait_timeout, | ||
133 | mode, timeout); | ||
134 | } | ||
135 | |||
136 | /** | ||
137 | * wait_on_bit_action - wait for a bit to be cleared | ||
138 | * @word: the word being waited on, a kernel virtual address | ||
139 | * @bit: the bit of the word being waited on | ||
140 | * @action: the function used to sleep, which may take special actions | ||
141 | * @mode: the task state to sleep in | ||
142 | * | ||
143 | * Use the standard hashed waitqueue table to wait for a bit | ||
144 | * to be cleared, and allow the waiting action to be specified. | ||
145 | * This is like wait_on_bit() but allows fine control of how the waiting | ||
146 | * is done. | ||
147 | * | ||
148 | * Returned value will be zero if the bit was cleared, or non-zero | ||
149 | * if the process received a signal and the mode permitted wakeup | ||
150 | * on that signal. | ||
151 | */ | ||
152 | static inline int | ||
153 | wait_on_bit_action(unsigned long *word, int bit, wait_bit_action_f *action, | ||
154 | unsigned mode) | ||
155 | { | ||
156 | might_sleep(); | ||
157 | if (!test_bit(bit, word)) | ||
158 | return 0; | ||
159 | return out_of_line_wait_on_bit(word, bit, action, mode); | ||
160 | } | ||
161 | |||
162 | /** | ||
163 | * wait_on_bit_lock - wait for a bit to be cleared, when wanting to set it | ||
164 | * @word: the word being waited on, a kernel virtual address | ||
165 | * @bit: the bit of the word being waited on | ||
166 | * @mode: the task state to sleep in | ||
167 | * | ||
168 | * There is a standard hashed waitqueue table for generic use. This | ||
169 | * is the part of the hashtable's accessor API that waits on a bit | ||
170 | * when one intends to set it, for instance, trying to lock bitflags. | ||
171 | * For instance, if one were to have waiters trying to set bitflag | ||
172 | * and waiting for it to clear before setting it, one would call | ||
173 | * wait_on_bit() in threads waiting to be able to set the bit. | ||
174 | * One uses wait_on_bit_lock() where one is waiting for the bit to | ||
175 | * clear with the intention of setting it, and when done, clearing it. | ||
176 | * | ||
177 | * Returns zero if the bit was (eventually) found to be clear and was | ||
178 | * set. Returns non-zero if a signal was delivered to the process and | ||
179 | * the @mode allows that signal to wake the process. | ||
180 | */ | ||
181 | static inline int | ||
182 | wait_on_bit_lock(unsigned long *word, int bit, unsigned mode) | ||
183 | { | ||
184 | might_sleep(); | ||
185 | if (!test_and_set_bit(bit, word)) | ||
186 | return 0; | ||
187 | return out_of_line_wait_on_bit_lock(word, bit, bit_wait, mode); | ||
188 | } | ||
189 | |||
190 | /** | ||
191 | * wait_on_bit_lock_io - wait for a bit to be cleared, when wanting to set it | ||
192 | * @word: the word being waited on, a kernel virtual address | ||
193 | * @bit: the bit of the word being waited on | ||
194 | * @mode: the task state to sleep in | ||
195 | * | ||
196 | * Use the standard hashed waitqueue table to wait for a bit | ||
197 | * to be cleared and then to atomically set it. This is similar | ||
198 | * to wait_on_bit(), but calls io_schedule() instead of schedule() | ||
199 | * for the actual waiting. | ||
200 | * | ||
201 | * Returns zero if the bit was (eventually) found to be clear and was | ||
202 | * set. Returns non-zero if a signal was delivered to the process and | ||
203 | * the @mode allows that signal to wake the process. | ||
204 | */ | ||
205 | static inline int | ||
206 | wait_on_bit_lock_io(unsigned long *word, int bit, unsigned mode) | ||
207 | { | ||
208 | might_sleep(); | ||
209 | if (!test_and_set_bit(bit, word)) | ||
210 | return 0; | ||
211 | return out_of_line_wait_on_bit_lock(word, bit, bit_wait_io, mode); | ||
212 | } | ||
213 | |||
214 | /** | ||
215 | * wait_on_bit_lock_action - wait for a bit to be cleared, when wanting to set it | ||
216 | * @word: the word being waited on, a kernel virtual address | ||
217 | * @bit: the bit of the word being waited on | ||
218 | * @action: the function used to sleep, which may take special actions | ||
219 | * @mode: the task state to sleep in | ||
220 | * | ||
221 | * Use the standard hashed waitqueue table to wait for a bit | ||
222 | * to be cleared and then to set it, and allow the waiting action | ||
223 | * to be specified. | ||
224 | * This is like wait_on_bit() but allows fine control of how the waiting | ||
225 | * is done. | ||
226 | * | ||
227 | * Returns zero if the bit was (eventually) found to be clear and was | ||
228 | * set. Returns non-zero if a signal was delivered to the process and | ||
229 | * the @mode allows that signal to wake the process. | ||
230 | */ | ||
231 | static inline int | ||
232 | wait_on_bit_lock_action(unsigned long *word, int bit, wait_bit_action_f *action, | ||
233 | unsigned mode) | ||
234 | { | ||
235 | might_sleep(); | ||
236 | if (!test_and_set_bit(bit, word)) | ||
237 | return 0; | ||
238 | return out_of_line_wait_on_bit_lock(word, bit, action, mode); | ||
239 | } | ||
240 | |||
241 | /** | ||
242 | * wait_on_atomic_t - Wait for an atomic_t to become 0 | ||
243 | * @val: The atomic value being waited on, a kernel virtual address | ||
244 | * @action: the function used to sleep, which may take special actions | ||
245 | * @mode: the task state to sleep in | ||
246 | * | ||
247 | * Wait for an atomic_t to become 0. We abuse the bit-wait waitqueue table for | ||
248 | * the purpose of getting a waitqueue, but we set the key to a bit number | ||
249 | * outside of the target 'word'. | ||
250 | */ | ||
251 | static inline | ||
252 | int wait_on_atomic_t(atomic_t *val, int (*action)(atomic_t *), unsigned mode) | ||
253 | { | ||
254 | might_sleep(); | ||
255 | if (atomic_read(val) == 0) | ||
256 | return 0; | ||
257 | return out_of_line_wait_on_atomic_t(val, action, mode); | ||
258 | } | ||
259 | |||
260 | #endif /* _LINUX_WAIT_BIT_H */ | ||