diff options
author | Tejun Heo <tj@kernel.org> | 2011-01-14 10:56:37 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-14 12:25:11 -0500 |
commit | 0ad53eeefcbb2620b6a71ffdaad4add20b450b8b (patch) | |
tree | 6f24c2d7b0a7554842544e51bd8e52159086669e | |
parent | e1fcc7e2a719d139322fab3f47cfbd4340cf3d82 (diff) |
afs: add afs_wq and use it instead of the system workqueue
flush_scheduled_work() is going away. afs needs to make sure all the
works it has queued have finished before being unloaded and there can
be arbitrary number of pending works. Add afs_wq and use it as the
flush domain instead of the system workqueue.
Also, convert cancel_delayed_work() + flush_scheduled_work() to
cancel_delayed_work_sync() in afs_mntpt_kill_timer().
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: David Howells <dhowells@redhat.com>
Cc: linux-afs@lists.infradead.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/afs/cmservice.c | 12 | ||||
-rw-r--r-- | fs/afs/internal.h | 1 | ||||
-rw-r--r-- | fs/afs/main.c | 13 | ||||
-rw-r--r-- | fs/afs/mntpt.c | 11 | ||||
-rw-r--r-- | fs/afs/rxrpc.c | 2 | ||||
-rw-r--r-- | fs/afs/server.c | 13 | ||||
-rw-r--r-- | fs/afs/vlocation.c | 14 |
7 files changed, 38 insertions, 28 deletions
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c index a3bcec75c54a..1c8c6cc6de30 100644 --- a/fs/afs/cmservice.c +++ b/fs/afs/cmservice.c | |||
@@ -289,7 +289,7 @@ static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb, | |||
289 | call->server = server; | 289 | call->server = server; |
290 | 290 | ||
291 | INIT_WORK(&call->work, SRXAFSCB_CallBack); | 291 | INIT_WORK(&call->work, SRXAFSCB_CallBack); |
292 | schedule_work(&call->work); | 292 | queue_work(afs_wq, &call->work); |
293 | return 0; | 293 | return 0; |
294 | } | 294 | } |
295 | 295 | ||
@@ -336,7 +336,7 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call, | |||
336 | call->server = server; | 336 | call->server = server; |
337 | 337 | ||
338 | INIT_WORK(&call->work, SRXAFSCB_InitCallBackState); | 338 | INIT_WORK(&call->work, SRXAFSCB_InitCallBackState); |
339 | schedule_work(&call->work); | 339 | queue_work(afs_wq, &call->work); |
340 | return 0; | 340 | return 0; |
341 | } | 341 | } |
342 | 342 | ||
@@ -367,7 +367,7 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call, | |||
367 | call->server = server; | 367 | call->server = server; |
368 | 368 | ||
369 | INIT_WORK(&call->work, SRXAFSCB_InitCallBackState); | 369 | INIT_WORK(&call->work, SRXAFSCB_InitCallBackState); |
370 | schedule_work(&call->work); | 370 | queue_work(afs_wq, &call->work); |
371 | return 0; | 371 | return 0; |
372 | } | 372 | } |
373 | 373 | ||
@@ -400,7 +400,7 @@ static int afs_deliver_cb_probe(struct afs_call *call, struct sk_buff *skb, | |||
400 | call->state = AFS_CALL_REPLYING; | 400 | call->state = AFS_CALL_REPLYING; |
401 | 401 | ||
402 | INIT_WORK(&call->work, SRXAFSCB_Probe); | 402 | INIT_WORK(&call->work, SRXAFSCB_Probe); |
403 | schedule_work(&call->work); | 403 | queue_work(afs_wq, &call->work); |
404 | return 0; | 404 | return 0; |
405 | } | 405 | } |
406 | 406 | ||
@@ -496,7 +496,7 @@ static int afs_deliver_cb_probe_uuid(struct afs_call *call, struct sk_buff *skb, | |||
496 | call->state = AFS_CALL_REPLYING; | 496 | call->state = AFS_CALL_REPLYING; |
497 | 497 | ||
498 | INIT_WORK(&call->work, SRXAFSCB_ProbeUuid); | 498 | INIT_WORK(&call->work, SRXAFSCB_ProbeUuid); |
499 | schedule_work(&call->work); | 499 | queue_work(afs_wq, &call->work); |
500 | return 0; | 500 | return 0; |
501 | } | 501 | } |
502 | 502 | ||
@@ -580,6 +580,6 @@ static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call, | |||
580 | call->state = AFS_CALL_REPLYING; | 580 | call->state = AFS_CALL_REPLYING; |
581 | 581 | ||
582 | INIT_WORK(&call->work, SRXAFSCB_TellMeAboutYourself); | 582 | INIT_WORK(&call->work, SRXAFSCB_TellMeAboutYourself); |
583 | schedule_work(&call->work); | 583 | queue_work(afs_wq, &call->work); |
584 | return 0; | 584 | return 0; |
585 | } | 585 | } |
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index ab6db5abaf53..58c633b80246 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
@@ -577,6 +577,7 @@ extern int afs_drop_inode(struct inode *); | |||
577 | /* | 577 | /* |
578 | * main.c | 578 | * main.c |
579 | */ | 579 | */ |
580 | extern struct workqueue_struct *afs_wq; | ||
580 | extern struct afs_uuid afs_uuid; | 581 | extern struct afs_uuid afs_uuid; |
581 | 582 | ||
582 | /* | 583 | /* |
diff --git a/fs/afs/main.c b/fs/afs/main.c index cfd1cbe25b22..42dd2e499ed8 100644 --- a/fs/afs/main.c +++ b/fs/afs/main.c | |||
@@ -30,6 +30,7 @@ module_param(rootcell, charp, 0); | |||
30 | MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list"); | 30 | MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list"); |
31 | 31 | ||
32 | struct afs_uuid afs_uuid; | 32 | struct afs_uuid afs_uuid; |
33 | struct workqueue_struct *afs_wq; | ||
33 | 34 | ||
34 | /* | 35 | /* |
35 | * get a client UUID | 36 | * get a client UUID |
@@ -87,10 +88,16 @@ static int __init afs_init(void) | |||
87 | if (ret < 0) | 88 | if (ret < 0) |
88 | return ret; | 89 | return ret; |
89 | 90 | ||
91 | /* create workqueue */ | ||
92 | ret = -ENOMEM; | ||
93 | afs_wq = alloc_workqueue("afs", 0, 0); | ||
94 | if (!afs_wq) | ||
95 | return ret; | ||
96 | |||
90 | /* register the /proc stuff */ | 97 | /* register the /proc stuff */ |
91 | ret = afs_proc_init(); | 98 | ret = afs_proc_init(); |
92 | if (ret < 0) | 99 | if (ret < 0) |
93 | return ret; | 100 | goto error_proc; |
94 | 101 | ||
95 | #ifdef CONFIG_AFS_FSCACHE | 102 | #ifdef CONFIG_AFS_FSCACHE |
96 | /* we want to be able to cache */ | 103 | /* we want to be able to cache */ |
@@ -140,6 +147,8 @@ error_cell_init: | |||
140 | error_cache: | 147 | error_cache: |
141 | #endif | 148 | #endif |
142 | afs_proc_cleanup(); | 149 | afs_proc_cleanup(); |
150 | error_proc: | ||
151 | destroy_workqueue(afs_wq); | ||
143 | rcu_barrier(); | 152 | rcu_barrier(); |
144 | printk(KERN_ERR "kAFS: failed to register: %d\n", ret); | 153 | printk(KERN_ERR "kAFS: failed to register: %d\n", ret); |
145 | return ret; | 154 | return ret; |
@@ -163,7 +172,7 @@ static void __exit afs_exit(void) | |||
163 | afs_purge_servers(); | 172 | afs_purge_servers(); |
164 | afs_callback_update_kill(); | 173 | afs_callback_update_kill(); |
165 | afs_vlocation_purge(); | 174 | afs_vlocation_purge(); |
166 | flush_scheduled_work(); | 175 | destroy_workqueue(afs_wq); |
167 | afs_cell_purge(); | 176 | afs_cell_purge(); |
168 | #ifdef CONFIG_AFS_FSCACHE | 177 | #ifdef CONFIG_AFS_FSCACHE |
169 | fscache_unregister_netfs(&afs_cache_netfs); | 178 | fscache_unregister_netfs(&afs_cache_netfs); |
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c index 6153417caf57..e83c0336e7b5 100644 --- a/fs/afs/mntpt.c +++ b/fs/afs/mntpt.c | |||
@@ -268,8 +268,8 @@ static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
268 | path_put(&nd->path); | 268 | path_put(&nd->path); |
269 | nd->path.mnt = newmnt; | 269 | nd->path.mnt = newmnt; |
270 | nd->path.dentry = dget(newmnt->mnt_root); | 270 | nd->path.dentry = dget(newmnt->mnt_root); |
271 | schedule_delayed_work(&afs_mntpt_expiry_timer, | 271 | queue_delayed_work(afs_wq, &afs_mntpt_expiry_timer, |
272 | afs_mntpt_expiry_timeout * HZ); | 272 | afs_mntpt_expiry_timeout * HZ); |
273 | break; | 273 | break; |
274 | case -EBUSY: | 274 | case -EBUSY: |
275 | /* someone else made a mount here whilst we were busy */ | 275 | /* someone else made a mount here whilst we were busy */ |
@@ -295,8 +295,8 @@ static void afs_mntpt_expiry_timed_out(struct work_struct *work) | |||
295 | 295 | ||
296 | if (!list_empty(&afs_vfsmounts)) { | 296 | if (!list_empty(&afs_vfsmounts)) { |
297 | mark_mounts_for_expiry(&afs_vfsmounts); | 297 | mark_mounts_for_expiry(&afs_vfsmounts); |
298 | schedule_delayed_work(&afs_mntpt_expiry_timer, | 298 | queue_delayed_work(afs_wq, &afs_mntpt_expiry_timer, |
299 | afs_mntpt_expiry_timeout * HZ); | 299 | afs_mntpt_expiry_timeout * HZ); |
300 | } | 300 | } |
301 | 301 | ||
302 | _leave(""); | 302 | _leave(""); |
@@ -310,6 +310,5 @@ void afs_mntpt_kill_timer(void) | |||
310 | _enter(""); | 310 | _enter(""); |
311 | 311 | ||
312 | ASSERT(list_empty(&afs_vfsmounts)); | 312 | ASSERT(list_empty(&afs_vfsmounts)); |
313 | cancel_delayed_work(&afs_mntpt_expiry_timer); | 313 | cancel_delayed_work_sync(&afs_mntpt_expiry_timer); |
314 | flush_scheduled_work(); | ||
315 | } | 314 | } |
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index 654d8fdbf01f..e45a323aebb4 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c | |||
@@ -410,7 +410,7 @@ static void afs_rx_interceptor(struct sock *sk, unsigned long user_call_ID, | |||
410 | if (!call) { | 410 | if (!call) { |
411 | /* its an incoming call for our callback service */ | 411 | /* its an incoming call for our callback service */ |
412 | skb_queue_tail(&afs_incoming_calls, skb); | 412 | skb_queue_tail(&afs_incoming_calls, skb); |
413 | schedule_work(&afs_collect_incoming_call_work); | 413 | queue_work(afs_wq, &afs_collect_incoming_call_work); |
414 | } else { | 414 | } else { |
415 | /* route the messages directly to the appropriate call */ | 415 | /* route the messages directly to the appropriate call */ |
416 | skb_queue_tail(&call->rx_queue, skb); | 416 | skb_queue_tail(&call->rx_queue, skb); |
diff --git a/fs/afs/server.c b/fs/afs/server.c index 9fdc7fe3a7bc..d59b7516e943 100644 --- a/fs/afs/server.c +++ b/fs/afs/server.c | |||
@@ -238,8 +238,8 @@ void afs_put_server(struct afs_server *server) | |||
238 | if (atomic_read(&server->usage) == 0) { | 238 | if (atomic_read(&server->usage) == 0) { |
239 | list_move_tail(&server->grave, &afs_server_graveyard); | 239 | list_move_tail(&server->grave, &afs_server_graveyard); |
240 | server->time_of_death = get_seconds(); | 240 | server->time_of_death = get_seconds(); |
241 | schedule_delayed_work(&afs_server_reaper, | 241 | queue_delayed_work(afs_wq, &afs_server_reaper, |
242 | afs_server_timeout * HZ); | 242 | afs_server_timeout * HZ); |
243 | } | 243 | } |
244 | spin_unlock(&afs_server_graveyard_lock); | 244 | spin_unlock(&afs_server_graveyard_lock); |
245 | _leave(" [dead]"); | 245 | _leave(" [dead]"); |
@@ -285,10 +285,11 @@ static void afs_reap_server(struct work_struct *work) | |||
285 | expiry = server->time_of_death + afs_server_timeout; | 285 | expiry = server->time_of_death + afs_server_timeout; |
286 | if (expiry > now) { | 286 | if (expiry > now) { |
287 | delay = (expiry - now) * HZ; | 287 | delay = (expiry - now) * HZ; |
288 | if (!schedule_delayed_work(&afs_server_reaper, delay)) { | 288 | if (!queue_delayed_work(afs_wq, &afs_server_reaper, |
289 | delay)) { | ||
289 | cancel_delayed_work(&afs_server_reaper); | 290 | cancel_delayed_work(&afs_server_reaper); |
290 | schedule_delayed_work(&afs_server_reaper, | 291 | queue_delayed_work(afs_wq, &afs_server_reaper, |
291 | delay); | 292 | delay); |
292 | } | 293 | } |
293 | break; | 294 | break; |
294 | } | 295 | } |
@@ -323,5 +324,5 @@ void __exit afs_purge_servers(void) | |||
323 | { | 324 | { |
324 | afs_server_timeout = 0; | 325 | afs_server_timeout = 0; |
325 | cancel_delayed_work(&afs_server_reaper); | 326 | cancel_delayed_work(&afs_server_reaper); |
326 | schedule_delayed_work(&afs_server_reaper, 0); | 327 | queue_delayed_work(afs_wq, &afs_server_reaper, 0); |
327 | } | 328 | } |
diff --git a/fs/afs/vlocation.c b/fs/afs/vlocation.c index 9ac260d1361d..431984d2e372 100644 --- a/fs/afs/vlocation.c +++ b/fs/afs/vlocation.c | |||
@@ -507,8 +507,8 @@ void afs_put_vlocation(struct afs_vlocation *vl) | |||
507 | _debug("buried"); | 507 | _debug("buried"); |
508 | list_move_tail(&vl->grave, &afs_vlocation_graveyard); | 508 | list_move_tail(&vl->grave, &afs_vlocation_graveyard); |
509 | vl->time_of_death = get_seconds(); | 509 | vl->time_of_death = get_seconds(); |
510 | schedule_delayed_work(&afs_vlocation_reap, | 510 | queue_delayed_work(afs_wq, &afs_vlocation_reap, |
511 | afs_vlocation_timeout * HZ); | 511 | afs_vlocation_timeout * HZ); |
512 | 512 | ||
513 | /* suspend updates on this record */ | 513 | /* suspend updates on this record */ |
514 | if (!list_empty(&vl->update)) { | 514 | if (!list_empty(&vl->update)) { |
@@ -561,11 +561,11 @@ static void afs_vlocation_reaper(struct work_struct *work) | |||
561 | if (expiry > now) { | 561 | if (expiry > now) { |
562 | delay = (expiry - now) * HZ; | 562 | delay = (expiry - now) * HZ; |
563 | _debug("delay %lu", delay); | 563 | _debug("delay %lu", delay); |
564 | if (!schedule_delayed_work(&afs_vlocation_reap, | 564 | if (!queue_delayed_work(afs_wq, &afs_vlocation_reap, |
565 | delay)) { | 565 | delay)) { |
566 | cancel_delayed_work(&afs_vlocation_reap); | 566 | cancel_delayed_work(&afs_vlocation_reap); |
567 | schedule_delayed_work(&afs_vlocation_reap, | 567 | queue_delayed_work(afs_wq, &afs_vlocation_reap, |
568 | delay); | 568 | delay); |
569 | } | 569 | } |
570 | break; | 570 | break; |
571 | } | 571 | } |
@@ -620,7 +620,7 @@ void afs_vlocation_purge(void) | |||
620 | destroy_workqueue(afs_vlocation_update_worker); | 620 | destroy_workqueue(afs_vlocation_update_worker); |
621 | 621 | ||
622 | cancel_delayed_work(&afs_vlocation_reap); | 622 | cancel_delayed_work(&afs_vlocation_reap); |
623 | schedule_delayed_work(&afs_vlocation_reap, 0); | 623 | queue_delayed_work(afs_wq, &afs_vlocation_reap, 0); |
624 | } | 624 | } |
625 | 625 | ||
626 | /* | 626 | /* |