diff options
Diffstat (limited to 'net/sunrpc/sched.c')
-rw-r--r-- | net/sunrpc/sched.c | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 6309f3b52c53..f56ebc5a08f7 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
@@ -270,17 +270,22 @@ static int rpc_wait_bit_interruptible(void *word) | |||
270 | 270 | ||
271 | static void rpc_set_active(struct rpc_task *task) | 271 | static void rpc_set_active(struct rpc_task *task) |
272 | { | 272 | { |
273 | struct rpc_clnt *clnt; | ||
273 | if (test_and_set_bit(RPC_TASK_ACTIVE, &task->tk_runstate) != 0) | 274 | if (test_and_set_bit(RPC_TASK_ACTIVE, &task->tk_runstate) != 0) |
274 | return; | 275 | return; |
275 | spin_lock(&rpc_sched_lock); | ||
276 | #ifdef RPC_DEBUG | 276 | #ifdef RPC_DEBUG |
277 | task->tk_magic = RPC_TASK_MAGIC_ID; | 277 | task->tk_magic = RPC_TASK_MAGIC_ID; |
278 | spin_lock(&rpc_sched_lock); | ||
278 | task->tk_pid = rpc_task_id++; | 279 | task->tk_pid = rpc_task_id++; |
280 | spin_unlock(&rpc_sched_lock); | ||
279 | #endif | 281 | #endif |
280 | /* Add to global list of all tasks */ | 282 | /* Add to global list of all tasks */ |
281 | if (task->tk_client) | 283 | clnt = task->tk_client; |
282 | list_add_tail(&task->tk_task, &task->tk_client->cl_tasks); | 284 | if (clnt != NULL) { |
283 | spin_unlock(&rpc_sched_lock); | 285 | spin_lock(&clnt->cl_lock); |
286 | list_add_tail(&task->tk_task, &clnt->cl_tasks); | ||
287 | spin_unlock(&clnt->cl_lock); | ||
288 | } | ||
284 | } | 289 | } |
285 | 290 | ||
286 | /* | 291 | /* |
@@ -924,10 +929,11 @@ static void rpc_release_task(struct rpc_task *task) | |||
924 | dprintk("RPC: %5u release task\n", task->tk_pid); | 929 | dprintk("RPC: %5u release task\n", task->tk_pid); |
925 | 930 | ||
926 | if (!list_empty(&task->tk_task)) { | 931 | if (!list_empty(&task->tk_task)) { |
932 | struct rpc_clnt *clnt = task->tk_client; | ||
927 | /* Remove from client task list */ | 933 | /* Remove from client task list */ |
928 | spin_lock(&rpc_sched_lock); | 934 | spin_lock(&clnt->cl_lock); |
929 | list_del(&task->tk_task); | 935 | list_del(&task->tk_task); |
930 | spin_unlock(&rpc_sched_lock); | 936 | spin_unlock(&clnt->cl_lock); |
931 | } | 937 | } |
932 | BUG_ON (RPC_IS_QUEUED(task)); | 938 | BUG_ON (RPC_IS_QUEUED(task)); |
933 | 939 | ||
@@ -970,12 +976,19 @@ EXPORT_SYMBOL(rpc_run_task); | |||
970 | * Kill all tasks for the given client. | 976 | * Kill all tasks for the given client. |
971 | * XXX: kill their descendants as well? | 977 | * XXX: kill their descendants as well? |
972 | */ | 978 | */ |
973 | static void rpc_killall_tasks_locked(struct list_head *head) | 979 | void rpc_killall_tasks(struct rpc_clnt *clnt) |
974 | { | 980 | { |
975 | struct rpc_task *rovr; | 981 | struct rpc_task *rovr; |
976 | 982 | ||
977 | 983 | ||
978 | list_for_each_entry(rovr, head, tk_task) { | 984 | if (list_empty(&clnt->cl_tasks)) |
985 | return; | ||
986 | dprintk("RPC: killing all tasks for client %p\n", clnt); | ||
987 | /* | ||
988 | * Spin lock all_tasks to prevent changes... | ||
989 | */ | ||
990 | spin_lock(&clnt->cl_lock); | ||
991 | list_for_each_entry(rovr, &clnt->cl_tasks, tk_task) { | ||
979 | if (! RPC_IS_ACTIVATED(rovr)) | 992 | if (! RPC_IS_ACTIVATED(rovr)) |
980 | continue; | 993 | continue; |
981 | if (!(rovr->tk_flags & RPC_TASK_KILLED)) { | 994 | if (!(rovr->tk_flags & RPC_TASK_KILLED)) { |
@@ -984,17 +997,7 @@ static void rpc_killall_tasks_locked(struct list_head *head) | |||
984 | rpc_wake_up_task(rovr); | 997 | rpc_wake_up_task(rovr); |
985 | } | 998 | } |
986 | } | 999 | } |
987 | } | 1000 | spin_unlock(&clnt->cl_lock); |
988 | |||
989 | void rpc_killall_tasks(struct rpc_clnt *clnt) | ||
990 | { | ||
991 | dprintk("RPC: killing all tasks for client %p\n", clnt); | ||
992 | /* | ||
993 | * Spin lock all_tasks to prevent changes... | ||
994 | */ | ||
995 | spin_lock(&rpc_sched_lock); | ||
996 | rpc_killall_tasks_locked(&clnt->cl_tasks); | ||
997 | spin_unlock(&rpc_sched_lock); | ||
998 | } | 1001 | } |
999 | 1002 | ||
1000 | static void rpciod_killall(void) | 1003 | static void rpciod_killall(void) |
@@ -1007,7 +1010,7 @@ static void rpciod_killall(void) | |||
1007 | 1010 | ||
1008 | spin_lock(&rpc_sched_lock); | 1011 | spin_lock(&rpc_sched_lock); |
1009 | list_for_each_entry(clnt, &all_clients, cl_clients) | 1012 | list_for_each_entry(clnt, &all_clients, cl_clients) |
1010 | rpc_killall_tasks_locked(&clnt->cl_tasks); | 1013 | rpc_killall_tasks(clnt); |
1011 | spin_unlock(&rpc_sched_lock); | 1014 | spin_unlock(&rpc_sched_lock); |
1012 | flush_workqueue(rpciod_workqueue); | 1015 | flush_workqueue(rpciod_workqueue); |
1013 | if (!list_empty(&all_clients)) | 1016 | if (!list_empty(&all_clients)) |
@@ -1110,6 +1113,9 @@ void rpc_show_tasks(void) | |||
1110 | printk("-pid- proc flgs status -client- -prog- --rqstp- -timeout " | 1113 | printk("-pid- proc flgs status -client- -prog- --rqstp- -timeout " |
1111 | "-rpcwait -action- ---ops--\n"); | 1114 | "-rpcwait -action- ---ops--\n"); |
1112 | list_for_each_entry(clnt, &all_clients, cl_clients) { | 1115 | list_for_each_entry(clnt, &all_clients, cl_clients) { |
1116 | if (list_empty(&clnt->cl_tasks)) | ||
1117 | continue; | ||
1118 | spin_lock(&clnt->cl_lock); | ||
1113 | list_for_each_entry(t, &clnt->cl_tasks, tk_task) { | 1119 | list_for_each_entry(t, &clnt->cl_tasks, tk_task) { |
1114 | const char *rpc_waitq = "none"; | 1120 | const char *rpc_waitq = "none"; |
1115 | 1121 | ||
@@ -1126,6 +1132,7 @@ void rpc_show_tasks(void) | |||
1126 | rpc_waitq, | 1132 | rpc_waitq, |
1127 | t->tk_action, t->tk_ops); | 1133 | t->tk_action, t->tk_ops); |
1128 | } | 1134 | } |
1135 | spin_unlock(&clnt->cl_lock); | ||
1129 | } | 1136 | } |
1130 | out: | 1137 | out: |
1131 | spin_unlock(&rpc_sched_lock); | 1138 | spin_unlock(&rpc_sched_lock); |