diff options
Diffstat (limited to 'drivers/md/bcache/closure.c')
-rw-r--r-- | drivers/md/bcache/closure.c | 103 |
1 files changed, 16 insertions, 87 deletions
diff --git a/drivers/md/bcache/closure.c b/drivers/md/bcache/closure.c index 9aba2017f0d1..dfff2410322e 100644 --- a/drivers/md/bcache/closure.c +++ b/drivers/md/bcache/closure.c | |||
@@ -11,17 +11,6 @@ | |||
11 | 11 | ||
12 | #include "closure.h" | 12 | #include "closure.h" |
13 | 13 | ||
14 | void closure_queue(struct closure *cl) | ||
15 | { | ||
16 | struct workqueue_struct *wq = cl->wq; | ||
17 | if (wq) { | ||
18 | INIT_WORK(&cl->work, cl->work.func); | ||
19 | BUG_ON(!queue_work(wq, &cl->work)); | ||
20 | } else | ||
21 | cl->fn(cl); | ||
22 | } | ||
23 | EXPORT_SYMBOL_GPL(closure_queue); | ||
24 | |||
25 | #define CL_FIELD(type, field) \ | 14 | #define CL_FIELD(type, field) \ |
26 | case TYPE_ ## type: \ | 15 | case TYPE_ ## type: \ |
27 | return &container_of(cl, struct type, cl)->field | 16 | return &container_of(cl, struct type, cl)->field |
@@ -30,17 +19,6 @@ static struct closure_waitlist *closure_waitlist(struct closure *cl) | |||
30 | { | 19 | { |
31 | switch (cl->type) { | 20 | switch (cl->type) { |
32 | CL_FIELD(closure_with_waitlist, wait); | 21 | CL_FIELD(closure_with_waitlist, wait); |
33 | CL_FIELD(closure_with_waitlist_and_timer, wait); | ||
34 | default: | ||
35 | return NULL; | ||
36 | } | ||
37 | } | ||
38 | |||
39 | static struct timer_list *closure_timer(struct closure *cl) | ||
40 | { | ||
41 | switch (cl->type) { | ||
42 | CL_FIELD(closure_with_timer, timer); | ||
43 | CL_FIELD(closure_with_waitlist_and_timer, timer); | ||
44 | default: | 22 | default: |
45 | return NULL; | 23 | return NULL; |
46 | } | 24 | } |
@@ -51,7 +29,7 @@ static inline void closure_put_after_sub(struct closure *cl, int flags) | |||
51 | int r = flags & CLOSURE_REMAINING_MASK; | 29 | int r = flags & CLOSURE_REMAINING_MASK; |
52 | 30 | ||
53 | BUG_ON(flags & CLOSURE_GUARD_MASK); | 31 | BUG_ON(flags & CLOSURE_GUARD_MASK); |
54 | BUG_ON(!r && (flags & ~(CLOSURE_DESTRUCTOR|CLOSURE_BLOCKING))); | 32 | BUG_ON(!r && (flags & ~CLOSURE_DESTRUCTOR)); |
55 | 33 | ||
56 | /* Must deliver precisely one wakeup */ | 34 | /* Must deliver precisely one wakeup */ |
57 | if (r == 1 && (flags & CLOSURE_SLEEPING)) | 35 | if (r == 1 && (flags & CLOSURE_SLEEPING)) |
@@ -59,7 +37,6 @@ static inline void closure_put_after_sub(struct closure *cl, int flags) | |||
59 | 37 | ||
60 | if (!r) { | 38 | if (!r) { |
61 | if (cl->fn && !(flags & CLOSURE_DESTRUCTOR)) { | 39 | if (cl->fn && !(flags & CLOSURE_DESTRUCTOR)) { |
62 | /* CLOSURE_BLOCKING might be set - clear it */ | ||
63 | atomic_set(&cl->remaining, | 40 | atomic_set(&cl->remaining, |
64 | CLOSURE_REMAINING_INITIALIZER); | 41 | CLOSURE_REMAINING_INITIALIZER); |
65 | closure_queue(cl); | 42 | closure_queue(cl); |
@@ -90,13 +67,13 @@ void closure_sub(struct closure *cl, int v) | |||
90 | { | 67 | { |
91 | closure_put_after_sub(cl, atomic_sub_return(v, &cl->remaining)); | 68 | closure_put_after_sub(cl, atomic_sub_return(v, &cl->remaining)); |
92 | } | 69 | } |
93 | EXPORT_SYMBOL_GPL(closure_sub); | 70 | EXPORT_SYMBOL(closure_sub); |
94 | 71 | ||
95 | void closure_put(struct closure *cl) | 72 | void closure_put(struct closure *cl) |
96 | { | 73 | { |
97 | closure_put_after_sub(cl, atomic_dec_return(&cl->remaining)); | 74 | closure_put_after_sub(cl, atomic_dec_return(&cl->remaining)); |
98 | } | 75 | } |
99 | EXPORT_SYMBOL_GPL(closure_put); | 76 | EXPORT_SYMBOL(closure_put); |
100 | 77 | ||
101 | static void set_waiting(struct closure *cl, unsigned long f) | 78 | static void set_waiting(struct closure *cl, unsigned long f) |
102 | { | 79 | { |
@@ -133,7 +110,7 @@ void __closure_wake_up(struct closure_waitlist *wait_list) | |||
133 | closure_sub(cl, CLOSURE_WAITING + 1); | 110 | closure_sub(cl, CLOSURE_WAITING + 1); |
134 | } | 111 | } |
135 | } | 112 | } |
136 | EXPORT_SYMBOL_GPL(__closure_wake_up); | 113 | EXPORT_SYMBOL(__closure_wake_up); |
137 | 114 | ||
138 | bool closure_wait(struct closure_waitlist *list, struct closure *cl) | 115 | bool closure_wait(struct closure_waitlist *list, struct closure *cl) |
139 | { | 116 | { |
@@ -146,7 +123,7 @@ bool closure_wait(struct closure_waitlist *list, struct closure *cl) | |||
146 | 123 | ||
147 | return true; | 124 | return true; |
148 | } | 125 | } |
149 | EXPORT_SYMBOL_GPL(closure_wait); | 126 | EXPORT_SYMBOL(closure_wait); |
150 | 127 | ||
151 | /** | 128 | /** |
152 | * closure_sync() - sleep until a closure a closure has nothing left to wait on | 129 | * closure_sync() - sleep until a closure a closure has nothing left to wait on |
@@ -169,7 +146,7 @@ void closure_sync(struct closure *cl) | |||
169 | 146 | ||
170 | __closure_end_sleep(cl); | 147 | __closure_end_sleep(cl); |
171 | } | 148 | } |
172 | EXPORT_SYMBOL_GPL(closure_sync); | 149 | EXPORT_SYMBOL(closure_sync); |
173 | 150 | ||
174 | /** | 151 | /** |
175 | * closure_trylock() - try to acquire the closure, without waiting | 152 | * closure_trylock() - try to acquire the closure, without waiting |
@@ -183,17 +160,17 @@ bool closure_trylock(struct closure *cl, struct closure *parent) | |||
183 | CLOSURE_REMAINING_INITIALIZER) != -1) | 160 | CLOSURE_REMAINING_INITIALIZER) != -1) |
184 | return false; | 161 | return false; |
185 | 162 | ||
186 | closure_set_ret_ip(cl); | ||
187 | |||
188 | smp_mb(); | 163 | smp_mb(); |
164 | |||
189 | cl->parent = parent; | 165 | cl->parent = parent; |
190 | if (parent) | 166 | if (parent) |
191 | closure_get(parent); | 167 | closure_get(parent); |
192 | 168 | ||
169 | closure_set_ret_ip(cl); | ||
193 | closure_debug_create(cl); | 170 | closure_debug_create(cl); |
194 | return true; | 171 | return true; |
195 | } | 172 | } |
196 | EXPORT_SYMBOL_GPL(closure_trylock); | 173 | EXPORT_SYMBOL(closure_trylock); |
197 | 174 | ||
198 | void __closure_lock(struct closure *cl, struct closure *parent, | 175 | void __closure_lock(struct closure *cl, struct closure *parent, |
199 | struct closure_waitlist *wait_list) | 176 | struct closure_waitlist *wait_list) |
@@ -205,57 +182,11 @@ void __closure_lock(struct closure *cl, struct closure *parent, | |||
205 | if (closure_trylock(cl, parent)) | 182 | if (closure_trylock(cl, parent)) |
206 | return; | 183 | return; |
207 | 184 | ||
208 | closure_wait_event_sync(wait_list, &wait, | 185 | closure_wait_event(wait_list, &wait, |
209 | atomic_read(&cl->remaining) == -1); | 186 | atomic_read(&cl->remaining) == -1); |
210 | } | 187 | } |
211 | } | 188 | } |
212 | EXPORT_SYMBOL_GPL(__closure_lock); | 189 | EXPORT_SYMBOL(__closure_lock); |
213 | |||
214 | static void closure_delay_timer_fn(unsigned long data) | ||
215 | { | ||
216 | struct closure *cl = (struct closure *) data; | ||
217 | closure_sub(cl, CLOSURE_TIMER + 1); | ||
218 | } | ||
219 | |||
220 | void do_closure_timer_init(struct closure *cl) | ||
221 | { | ||
222 | struct timer_list *timer = closure_timer(cl); | ||
223 | |||
224 | init_timer(timer); | ||
225 | timer->data = (unsigned long) cl; | ||
226 | timer->function = closure_delay_timer_fn; | ||
227 | } | ||
228 | EXPORT_SYMBOL_GPL(do_closure_timer_init); | ||
229 | |||
230 | bool __closure_delay(struct closure *cl, unsigned long delay, | ||
231 | struct timer_list *timer) | ||
232 | { | ||
233 | if (atomic_read(&cl->remaining) & CLOSURE_TIMER) | ||
234 | return false; | ||
235 | |||
236 | BUG_ON(timer_pending(timer)); | ||
237 | |||
238 | timer->expires = jiffies + delay; | ||
239 | |||
240 | atomic_add(CLOSURE_TIMER + 1, &cl->remaining); | ||
241 | add_timer(timer); | ||
242 | return true; | ||
243 | } | ||
244 | EXPORT_SYMBOL_GPL(__closure_delay); | ||
245 | |||
246 | void __closure_flush(struct closure *cl, struct timer_list *timer) | ||
247 | { | ||
248 | if (del_timer(timer)) | ||
249 | closure_sub(cl, CLOSURE_TIMER + 1); | ||
250 | } | ||
251 | EXPORT_SYMBOL_GPL(__closure_flush); | ||
252 | |||
253 | void __closure_flush_sync(struct closure *cl, struct timer_list *timer) | ||
254 | { | ||
255 | if (del_timer_sync(timer)) | ||
256 | closure_sub(cl, CLOSURE_TIMER + 1); | ||
257 | } | ||
258 | EXPORT_SYMBOL_GPL(__closure_flush_sync); | ||
259 | 190 | ||
260 | #ifdef CONFIG_BCACHE_CLOSURES_DEBUG | 191 | #ifdef CONFIG_BCACHE_CLOSURES_DEBUG |
261 | 192 | ||
@@ -273,7 +204,7 @@ void closure_debug_create(struct closure *cl) | |||
273 | list_add(&cl->all, &closure_list); | 204 | list_add(&cl->all, &closure_list); |
274 | spin_unlock_irqrestore(&closure_list_lock, flags); | 205 | spin_unlock_irqrestore(&closure_list_lock, flags); |
275 | } | 206 | } |
276 | EXPORT_SYMBOL_GPL(closure_debug_create); | 207 | EXPORT_SYMBOL(closure_debug_create); |
277 | 208 | ||
278 | void closure_debug_destroy(struct closure *cl) | 209 | void closure_debug_destroy(struct closure *cl) |
279 | { | 210 | { |
@@ -286,7 +217,7 @@ void closure_debug_destroy(struct closure *cl) | |||
286 | list_del(&cl->all); | 217 | list_del(&cl->all); |
287 | spin_unlock_irqrestore(&closure_list_lock, flags); | 218 | spin_unlock_irqrestore(&closure_list_lock, flags); |
288 | } | 219 | } |
289 | EXPORT_SYMBOL_GPL(closure_debug_destroy); | 220 | EXPORT_SYMBOL(closure_debug_destroy); |
290 | 221 | ||
291 | static struct dentry *debug; | 222 | static struct dentry *debug; |
292 | 223 | ||
@@ -304,14 +235,12 @@ static int debug_seq_show(struct seq_file *f, void *data) | |||
304 | cl, (void *) cl->ip, cl->fn, cl->parent, | 235 | cl, (void *) cl->ip, cl->fn, cl->parent, |
305 | r & CLOSURE_REMAINING_MASK); | 236 | r & CLOSURE_REMAINING_MASK); |
306 | 237 | ||
307 | seq_printf(f, "%s%s%s%s%s%s\n", | 238 | seq_printf(f, "%s%s%s%s\n", |
308 | test_bit(WORK_STRUCT_PENDING, | 239 | test_bit(WORK_STRUCT_PENDING, |
309 | work_data_bits(&cl->work)) ? "Q" : "", | 240 | work_data_bits(&cl->work)) ? "Q" : "", |
310 | r & CLOSURE_RUNNING ? "R" : "", | 241 | r & CLOSURE_RUNNING ? "R" : "", |
311 | r & CLOSURE_BLOCKING ? "B" : "", | ||
312 | r & CLOSURE_STACK ? "S" : "", | 242 | r & CLOSURE_STACK ? "S" : "", |
313 | r & CLOSURE_SLEEPING ? "Sl" : "", | 243 | r & CLOSURE_SLEEPING ? "Sl" : ""); |
314 | r & CLOSURE_TIMER ? "T" : ""); | ||
315 | 244 | ||
316 | if (r & CLOSURE_WAITING) | 245 | if (r & CLOSURE_WAITING) |
317 | seq_printf(f, " W %pF\n", | 246 | seq_printf(f, " W %pF\n", |