afs: add afs_wq and use it instead of the system workqueue
authorTejun Heo <tj@kernel.org>
Fri, 14 Jan 2011 15:56:37 +0000 (15:56 +0000)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Jan 2011 17:25:11 +0000 (09:25 -0800)
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>
fs/afs/cmservice.c
fs/afs/internal.h
fs/afs/main.c
fs/afs/mntpt.c
fs/afs/rxrpc.c
fs/afs/server.c
fs/afs/vlocation.c

index a3bcec7..1c8c6cc 100644 (file)
@@ -289,7 +289,7 @@ static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb,
        call->server = server;
 
        INIT_WORK(&call->work, SRXAFSCB_CallBack);
-       schedule_work(&call->work);
+       queue_work(afs_wq, &call->work);
        return 0;
 }
 
@@ -336,7 +336,7 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call,
        call->server = server;
 
        INIT_WORK(&call->work, SRXAFSCB_InitCallBackState);
-       schedule_work(&call->work);
+       queue_work(afs_wq, &call->work);
        return 0;
 }
 
@@ -367,7 +367,7 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call,
        call->server = server;
 
        INIT_WORK(&call->work, SRXAFSCB_InitCallBackState);
-       schedule_work(&call->work);
+       queue_work(afs_wq, &call->work);
        return 0;
 }
 
@@ -400,7 +400,7 @@ static int afs_deliver_cb_probe(struct afs_call *call, struct sk_buff *skb,
        call->state = AFS_CALL_REPLYING;
 
        INIT_WORK(&call->work, SRXAFSCB_Probe);
-       schedule_work(&call->work);
+       queue_work(afs_wq, &call->work);
        return 0;
 }
 
@@ -496,7 +496,7 @@ static int afs_deliver_cb_probe_uuid(struct afs_call *call, struct sk_buff *skb,
        call->state = AFS_CALL_REPLYING;
 
        INIT_WORK(&call->work, SRXAFSCB_ProbeUuid);
-       schedule_work(&call->work);
+       queue_work(afs_wq, &call->work);
        return 0;
 }
 
@@ -580,6 +580,6 @@ static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call,
        call->state = AFS_CALL_REPLYING;
 
        INIT_WORK(&call->work, SRXAFSCB_TellMeAboutYourself);
-       schedule_work(&call->work);
+       queue_work(afs_wq, &call->work);
        return 0;
 }
index ab6db5a..58c633b 100644 (file)
@@ -577,6 +577,7 @@ extern int afs_drop_inode(struct inode *);
 /*
  * main.c
  */
+extern struct workqueue_struct *afs_wq;
 extern struct afs_uuid afs_uuid;
 
 /*
index cfd1cbe..42dd2e4 100644 (file)
@@ -30,6 +30,7 @@ module_param(rootcell, charp, 0);
 MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list");
 
 struct afs_uuid afs_uuid;
+struct workqueue_struct *afs_wq;
 
 /*
  * get a client UUID
@@ -87,10 +88,16 @@ static int __init afs_init(void)
        if (ret < 0)
                return ret;
 
+       /* create workqueue */
+       ret = -ENOMEM;
+       afs_wq = alloc_workqueue("afs", 0, 0);
+       if (!afs_wq)
+               return ret;
+
        /* register the /proc stuff */
        ret = afs_proc_init();
        if (ret < 0)
-               return ret;
+               goto error_proc;
 
 #ifdef CONFIG_AFS_FSCACHE
        /* we want to be able to cache */
@@ -140,6 +147,8 @@ error_cell_init:
 error_cache:
 #endif
        afs_proc_cleanup();
+error_proc:
+       destroy_workqueue(afs_wq);
        rcu_barrier();
        printk(KERN_ERR "kAFS: failed to register: %d\n", ret);
        return ret;
@@ -163,7 +172,7 @@ static void __exit afs_exit(void)
        afs_purge_servers();
        afs_callback_update_kill();
        afs_vlocation_purge();
-       flush_scheduled_work();
+       destroy_workqueue(afs_wq);
        afs_cell_purge();
 #ifdef CONFIG_AFS_FSCACHE
        fscache_unregister_netfs(&afs_cache_netfs);
index 6153417..e83c033 100644 (file)
@@ -268,8 +268,8 @@ static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
                path_put(&nd->path);
                nd->path.mnt = newmnt;
                nd->path.dentry = dget(newmnt->mnt_root);
-               schedule_delayed_work(&afs_mntpt_expiry_timer,
-                                     afs_mntpt_expiry_timeout * HZ);
+               queue_delayed_work(afs_wq, &afs_mntpt_expiry_timer,
+                                  afs_mntpt_expiry_timeout * HZ);
                break;
        case -EBUSY:
                /* 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)
 
        if (!list_empty(&afs_vfsmounts)) {
                mark_mounts_for_expiry(&afs_vfsmounts);
-               schedule_delayed_work(&afs_mntpt_expiry_timer,
-                                     afs_mntpt_expiry_timeout * HZ);
+               queue_delayed_work(afs_wq, &afs_mntpt_expiry_timer,
+                                  afs_mntpt_expiry_timeout * HZ);
        }
 
        _leave("");
@@ -310,6 +310,5 @@ void afs_mntpt_kill_timer(void)
        _enter("");
 
        ASSERT(list_empty(&afs_vfsmounts));
-       cancel_delayed_work(&afs_mntpt_expiry_timer);
-       flush_scheduled_work();
+       cancel_delayed_work_sync(&afs_mntpt_expiry_timer);
 }
index 654d8fd..e45a323 100644 (file)
@@ -410,7 +410,7 @@ static void afs_rx_interceptor(struct sock *sk, unsigned long user_call_ID,
        if (!call) {
                /* its an incoming call for our callback service */
                skb_queue_tail(&afs_incoming_calls, skb);
-               schedule_work(&afs_collect_incoming_call_work);
+               queue_work(afs_wq, &afs_collect_incoming_call_work);
        } else {
                /* route the messages directly to the appropriate call */
                skb_queue_tail(&call->rx_queue, skb);
index 9fdc7fe..d59b751 100644 (file)
@@ -238,8 +238,8 @@ void afs_put_server(struct afs_server *server)
        if (atomic_read(&server->usage) == 0) {
                list_move_tail(&server->grave, &afs_server_graveyard);
                server->time_of_death = get_seconds();
-               schedule_delayed_work(&afs_server_reaper,
-                                     afs_server_timeout * HZ);
+               queue_delayed_work(afs_wq, &afs_server_reaper,
+                                  afs_server_timeout * HZ);
        }
        spin_unlock(&afs_server_graveyard_lock);
        _leave(" [dead]");
@@ -285,10 +285,11 @@ static void afs_reap_server(struct work_struct *work)
                expiry = server->time_of_death + afs_server_timeout;
                if (expiry > now) {
                        delay = (expiry - now) * HZ;
-                       if (!schedule_delayed_work(&afs_server_reaper, delay)) {
+                       if (!queue_delayed_work(afs_wq, &afs_server_reaper,
+                                               delay)) {
                                cancel_delayed_work(&afs_server_reaper);
-                               schedule_delayed_work(&afs_server_reaper,
-                                                     delay);
+                               queue_delayed_work(afs_wq, &afs_server_reaper,
+                                                  delay);
                        }
                        break;
                }
@@ -323,5 +324,5 @@ void __exit afs_purge_servers(void)
 {
        afs_server_timeout = 0;
        cancel_delayed_work(&afs_server_reaper);
-       schedule_delayed_work(&afs_server_reaper, 0);
+       queue_delayed_work(afs_wq, &afs_server_reaper, 0);
 }
index 9ac260d..431984d 100644 (file)
@@ -507,8 +507,8 @@ void afs_put_vlocation(struct afs_vlocation *vl)
                _debug("buried");
                list_move_tail(&vl->grave, &afs_vlocation_graveyard);
                vl->time_of_death = get_seconds();
-               schedule_delayed_work(&afs_vlocation_reap,
-                                     afs_vlocation_timeout * HZ);
+               queue_delayed_work(afs_wq, &afs_vlocation_reap,
+                                  afs_vlocation_timeout * HZ);
 
                /* suspend updates on this record */
                if (!list_empty(&vl->update)) {
@@ -561,11 +561,11 @@ static void afs_vlocation_reaper(struct work_struct *work)
                if (expiry > now) {
                        delay = (expiry - now) * HZ;
                        _debug("delay %lu", delay);
-                       if (!schedule_delayed_work(&afs_vlocation_reap,
-                                                  delay)) {
+                       if (!queue_delayed_work(afs_wq, &afs_vlocation_reap,
+                                               delay)) {
                                cancel_delayed_work(&afs_vlocation_reap);
-                               schedule_delayed_work(&afs_vlocation_reap,
-                                                     delay);
+                               queue_delayed_work(afs_wq, &afs_vlocation_reap,
+                                                  delay);
                        }
                        break;
                }
@@ -620,7 +620,7 @@ void afs_vlocation_purge(void)
        destroy_workqueue(afs_vlocation_update_worker);
 
        cancel_delayed_work(&afs_vlocation_reap);
-       schedule_delayed_work(&afs_vlocation_reap, 0);
+       queue_delayed_work(afs_wq, &afs_vlocation_reap, 0);
 }
 
 /*