aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-01-14 10:56:37 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-14 12:25:11 -0500
commit0ad53eeefcbb2620b6a71ffdaad4add20b450b8b (patch)
tree6f24c2d7b0a7554842544e51bd8e52159086669e
parente1fcc7e2a719d139322fab3f47cfbd4340cf3d82 (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.c12
-rw-r--r--fs/afs/internal.h1
-rw-r--r--fs/afs/main.c13
-rw-r--r--fs/afs/mntpt.c11
-rw-r--r--fs/afs/rxrpc.c2
-rw-r--r--fs/afs/server.c13
-rw-r--r--fs/afs/vlocation.c14
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 */
580extern struct workqueue_struct *afs_wq;
580extern struct afs_uuid afs_uuid; 581extern 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);
30MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list"); 30MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list");
31 31
32struct afs_uuid afs_uuid; 32struct afs_uuid afs_uuid;
33struct 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:
140error_cache: 147error_cache:
141#endif 148#endif
142 afs_proc_cleanup(); 149 afs_proc_cleanup();
150error_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/*