aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/bcache/closure.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/bcache/closure.c')
-rw-r--r--drivers/md/bcache/closure.c103
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
14void 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}
23EXPORT_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
39static 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}
93EXPORT_SYMBOL_GPL(closure_sub); 70EXPORT_SYMBOL(closure_sub);
94 71
95void closure_put(struct closure *cl) 72void 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}
99EXPORT_SYMBOL_GPL(closure_put); 76EXPORT_SYMBOL(closure_put);
100 77
101static void set_waiting(struct closure *cl, unsigned long f) 78static 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}
136EXPORT_SYMBOL_GPL(__closure_wake_up); 113EXPORT_SYMBOL(__closure_wake_up);
137 114
138bool closure_wait(struct closure_waitlist *list, struct closure *cl) 115bool 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}
149EXPORT_SYMBOL_GPL(closure_wait); 126EXPORT_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}
172EXPORT_SYMBOL_GPL(closure_sync); 149EXPORT_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}
196EXPORT_SYMBOL_GPL(closure_trylock); 173EXPORT_SYMBOL(closure_trylock);
197 174
198void __closure_lock(struct closure *cl, struct closure *parent, 175void __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}
212EXPORT_SYMBOL_GPL(__closure_lock); 189EXPORT_SYMBOL(__closure_lock);
213
214static 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
220void 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}
228EXPORT_SYMBOL_GPL(do_closure_timer_init);
229
230bool __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}
244EXPORT_SYMBOL_GPL(__closure_delay);
245
246void __closure_flush(struct closure *cl, struct timer_list *timer)
247{
248 if (del_timer(timer))
249 closure_sub(cl, CLOSURE_TIMER + 1);
250}
251EXPORT_SYMBOL_GPL(__closure_flush);
252
253void __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}
258EXPORT_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}
276EXPORT_SYMBOL_GPL(closure_debug_create); 207EXPORT_SYMBOL(closure_debug_create);
277 208
278void closure_debug_destroy(struct closure *cl) 209void 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}
289EXPORT_SYMBOL_GPL(closure_debug_destroy); 220EXPORT_SYMBOL(closure_debug_destroy);
290 221
291static struct dentry *debug; 222static 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",