aboutsummaryrefslogtreecommitdiffstats
path: root/net/9p/trans_fd.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-02-01 05:42:43 -0500
committerTejun Heo <tj@kernel.org>2011-02-01 05:42:43 -0500
commitaa70c585b15f64da6948bdacc7a7692addd65364 (patch)
tree8ba61c488f8f51e78fdcae273b17e5cbe8c0ae7c /net/9p/trans_fd.c
parent61edeeed917958dce5b43134d6704451ddf421fa (diff)
net/9p: replace p9_poll_task with a work
Now that cmwq can handle high concurrency, it's more efficient to use work than a dedicated kthread. Convert p9_poll_proc() to a work function for p9_poll_work and make p9_pollwake() schedule it on each poll event. The work is sync flushed on module exit. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Eric Van Hensbergen <ericvh@gmail.com> Cc: Ron Minnich <rminnich@sandia.gov> Cc: Latchesar Ionkov <lucho@ionkov.net> Cc: v9fs-developer@lists.sourceforge.net
Diffstat (limited to 'net/9p/trans_fd.c')
-rw-r--r--net/9p/trans_fd.c32
1 files changed, 8 insertions, 24 deletions
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index e9f797d24414..a30471e51740 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -153,9 +153,11 @@ struct p9_conn {
153 unsigned long wsched; 153 unsigned long wsched;
154}; 154};
155 155
156static void p9_poll_workfn(struct work_struct *work);
157
156static DEFINE_SPINLOCK(p9_poll_lock); 158static DEFINE_SPINLOCK(p9_poll_lock);
157static LIST_HEAD(p9_poll_pending_list); 159static LIST_HEAD(p9_poll_pending_list);
158static struct task_struct *p9_poll_task; 160static DECLARE_WORK(p9_poll_work, p9_poll_workfn);
159 161
160static void p9_mux_poll_stop(struct p9_conn *m) 162static void p9_mux_poll_stop(struct p9_conn *m)
161{ 163{
@@ -515,15 +517,14 @@ static int p9_pollwake(wait_queue_t *wait, unsigned mode, int sync, void *key)
515 container_of(wait, struct p9_poll_wait, wait); 517 container_of(wait, struct p9_poll_wait, wait);
516 struct p9_conn *m = pwait->conn; 518 struct p9_conn *m = pwait->conn;
517 unsigned long flags; 519 unsigned long flags;
518 DECLARE_WAITQUEUE(dummy_wait, p9_poll_task);
519 520
520 spin_lock_irqsave(&p9_poll_lock, flags); 521 spin_lock_irqsave(&p9_poll_lock, flags);
521 if (list_empty(&m->poll_pending_link)) 522 if (list_empty(&m->poll_pending_link))
522 list_add_tail(&m->poll_pending_link, &p9_poll_pending_list); 523 list_add_tail(&m->poll_pending_link, &p9_poll_pending_list);
523 spin_unlock_irqrestore(&p9_poll_lock, flags); 524 spin_unlock_irqrestore(&p9_poll_lock, flags);
524 525
525 /* perform the default wake up operation */ 526 schedule_work(&p9_poll_work);
526 return default_wake_function(&dummy_wait, mode, sync, key); 527 return 1;
527} 528}
528 529
529/** 530/**
@@ -1046,12 +1047,12 @@ static struct p9_trans_module p9_fd_trans = {
1046 * 1047 *
1047 */ 1048 */
1048 1049
1049static int p9_poll_proc(void *a) 1050static void p9_poll_workfn(struct work_struct *work)
1050{ 1051{
1051 unsigned long flags; 1052 unsigned long flags;
1052 1053
1053 P9_DPRINTK(P9_DEBUG_TRANS, "start %p\n", current); 1054 P9_DPRINTK(P9_DEBUG_TRANS, "start %p\n", current);
1054 repeat: 1055
1055 spin_lock_irqsave(&p9_poll_lock, flags); 1056 spin_lock_irqsave(&p9_poll_lock, flags);
1056 while (!list_empty(&p9_poll_pending_list)) { 1057 while (!list_empty(&p9_poll_pending_list)) {
1057 struct p9_conn *conn = list_first_entry(&p9_poll_pending_list, 1058 struct p9_conn *conn = list_first_entry(&p9_poll_pending_list,
@@ -1066,28 +1067,11 @@ static int p9_poll_proc(void *a)
1066 } 1067 }
1067 spin_unlock_irqrestore(&p9_poll_lock, flags); 1068 spin_unlock_irqrestore(&p9_poll_lock, flags);
1068 1069
1069 set_current_state(TASK_INTERRUPTIBLE);
1070 if (list_empty(&p9_poll_pending_list)) {
1071 P9_DPRINTK(P9_DEBUG_TRANS, "sleeping...\n");
1072 schedule();
1073 }
1074 __set_current_state(TASK_RUNNING);
1075
1076 if (!kthread_should_stop())
1077 goto repeat;
1078
1079 P9_DPRINTK(P9_DEBUG_TRANS, "finish\n"); 1070 P9_DPRINTK(P9_DEBUG_TRANS, "finish\n");
1080 return 0;
1081} 1071}
1082 1072
1083int p9_trans_fd_init(void) 1073int p9_trans_fd_init(void)
1084{ 1074{
1085 p9_poll_task = kthread_run(p9_poll_proc, NULL, "v9fs-poll");
1086 if (IS_ERR(p9_poll_task)) {
1087 printk(KERN_WARNING "v9fs: mux: creating poll task failed\n");
1088 return PTR_ERR(p9_poll_task);
1089 }
1090
1091 v9fs_register_trans(&p9_tcp_trans); 1075 v9fs_register_trans(&p9_tcp_trans);
1092 v9fs_register_trans(&p9_unix_trans); 1076 v9fs_register_trans(&p9_unix_trans);
1093 v9fs_register_trans(&p9_fd_trans); 1077 v9fs_register_trans(&p9_fd_trans);
@@ -1097,7 +1081,7 @@ int p9_trans_fd_init(void)
1097 1081
1098void p9_trans_fd_exit(void) 1082void p9_trans_fd_exit(void)
1099{ 1083{
1100 kthread_stop(p9_poll_task); 1084 flush_work_sync(&p9_poll_work);
1101 v9fs_unregister_trans(&p9_tcp_trans); 1085 v9fs_unregister_trans(&p9_tcp_trans);
1102 v9fs_unregister_trans(&p9_unix_trans); 1086 v9fs_unregister_trans(&p9_unix_trans);
1103 v9fs_unregister_trans(&p9_fd_trans); 1087 v9fs_unregister_trans(&p9_fd_trans);