diff options
author | Tejun Heo <tj@kernel.org> | 2011-02-01 05:42:43 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2011-02-01 05:42:43 -0500 |
commit | aa70c585b15f64da6948bdacc7a7692addd65364 (patch) | |
tree | 8ba61c488f8f51e78fdcae273b17e5cbe8c0ae7c /net/9p/trans_fd.c | |
parent | 61edeeed917958dce5b43134d6704451ddf421fa (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.c | 32 |
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 | ||
156 | static void p9_poll_workfn(struct work_struct *work); | ||
157 | |||
156 | static DEFINE_SPINLOCK(p9_poll_lock); | 158 | static DEFINE_SPINLOCK(p9_poll_lock); |
157 | static LIST_HEAD(p9_poll_pending_list); | 159 | static LIST_HEAD(p9_poll_pending_list); |
158 | static struct task_struct *p9_poll_task; | 160 | static DECLARE_WORK(p9_poll_work, p9_poll_workfn); |
159 | 161 | ||
160 | static void p9_mux_poll_stop(struct p9_conn *m) | 162 | static 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 | ||
1049 | static int p9_poll_proc(void *a) | 1050 | static 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 | ||
1083 | int p9_trans_fd_init(void) | 1073 | int 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 | ||
1098 | void p9_trans_fd_exit(void) | 1082 | void 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); |