diff options
Diffstat (limited to 'net/sunrpc/sched.c')
-rw-r--r-- | net/sunrpc/sched.c | 104 |
1 files changed, 17 insertions, 87 deletions
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 4a843b883b89..cace6049e4a5 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
@@ -246,17 +246,8 @@ static inline void rpc_task_set_debuginfo(struct rpc_task *task) | |||
246 | 246 | ||
247 | static void rpc_set_active(struct rpc_task *task) | 247 | static void rpc_set_active(struct rpc_task *task) |
248 | { | 248 | { |
249 | struct rpc_clnt *clnt; | ||
250 | if (test_and_set_bit(RPC_TASK_ACTIVE, &task->tk_runstate) != 0) | ||
251 | return; | ||
252 | rpc_task_set_debuginfo(task); | 249 | rpc_task_set_debuginfo(task); |
253 | /* Add to global list of all tasks */ | 250 | set_bit(RPC_TASK_ACTIVE, &task->tk_runstate); |
254 | clnt = task->tk_client; | ||
255 | if (clnt != NULL) { | ||
256 | spin_lock(&clnt->cl_lock); | ||
257 | list_add_tail(&task->tk_task, &clnt->cl_tasks); | ||
258 | spin_unlock(&clnt->cl_lock); | ||
259 | } | ||
260 | } | 251 | } |
261 | 252 | ||
262 | /* | 253 | /* |
@@ -319,11 +310,6 @@ static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, | |||
319 | dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n", | 310 | dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n", |
320 | task->tk_pid, rpc_qname(q), jiffies); | 311 | task->tk_pid, rpc_qname(q), jiffies); |
321 | 312 | ||
322 | if (!RPC_IS_ASYNC(task) && !RPC_IS_ACTIVATED(task)) { | ||
323 | printk(KERN_ERR "RPC: Inactive synchronous task put to sleep!\n"); | ||
324 | return; | ||
325 | } | ||
326 | |||
327 | __rpc_add_wait_queue(q, task); | 313 | __rpc_add_wait_queue(q, task); |
328 | 314 | ||
329 | BUG_ON(task->tk_callback != NULL); | 315 | BUG_ON(task->tk_callback != NULL); |
@@ -334,8 +320,8 @@ static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, | |||
334 | void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, | 320 | void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, |
335 | rpc_action action) | 321 | rpc_action action) |
336 | { | 322 | { |
337 | /* Mark the task as being activated if so needed */ | 323 | /* We shouldn't ever put an inactive task to sleep */ |
338 | rpc_set_active(task); | 324 | BUG_ON(!RPC_IS_ACTIVATED(task)); |
339 | 325 | ||
340 | /* | 326 | /* |
341 | * Protect the queue operations. | 327 | * Protect the queue operations. |
@@ -406,14 +392,6 @@ void rpc_wake_up_queued_task(struct rpc_wait_queue *queue, struct rpc_task *task | |||
406 | EXPORT_SYMBOL_GPL(rpc_wake_up_queued_task); | 392 | EXPORT_SYMBOL_GPL(rpc_wake_up_queued_task); |
407 | 393 | ||
408 | /* | 394 | /* |
409 | * Wake up the specified task | ||
410 | */ | ||
411 | static void rpc_wake_up_task(struct rpc_task *task) | ||
412 | { | ||
413 | rpc_wake_up_queued_task(task->tk_waitqueue, task); | ||
414 | } | ||
415 | |||
416 | /* | ||
417 | * Wake up the next task on a priority queue. | 395 | * Wake up the next task on a priority queue. |
418 | */ | 396 | */ |
419 | static struct rpc_task * __rpc_wake_up_next_priority(struct rpc_wait_queue *queue) | 397 | static struct rpc_task * __rpc_wake_up_next_priority(struct rpc_wait_queue *queue) |
@@ -600,7 +578,15 @@ void rpc_exit_task(struct rpc_task *task) | |||
600 | } | 578 | } |
601 | } | 579 | } |
602 | } | 580 | } |
603 | EXPORT_SYMBOL_GPL(rpc_exit_task); | 581 | |
582 | void rpc_exit(struct rpc_task *task, int status) | ||
583 | { | ||
584 | task->tk_status = status; | ||
585 | task->tk_action = rpc_exit_task; | ||
586 | if (RPC_IS_QUEUED(task)) | ||
587 | rpc_wake_up_queued_task(task->tk_waitqueue, task); | ||
588 | } | ||
589 | EXPORT_SYMBOL_GPL(rpc_exit); | ||
604 | 590 | ||
605 | void rpc_release_calldata(const struct rpc_call_ops *ops, void *calldata) | 591 | void rpc_release_calldata(const struct rpc_call_ops *ops, void *calldata) |
606 | { | 592 | { |
@@ -690,7 +676,6 @@ static void __rpc_execute(struct rpc_task *task) | |||
690 | dprintk("RPC: %5u got signal\n", task->tk_pid); | 676 | dprintk("RPC: %5u got signal\n", task->tk_pid); |
691 | task->tk_flags |= RPC_TASK_KILLED; | 677 | task->tk_flags |= RPC_TASK_KILLED; |
692 | rpc_exit(task, -ERESTARTSYS); | 678 | rpc_exit(task, -ERESTARTSYS); |
693 | rpc_wake_up_task(task); | ||
694 | } | 679 | } |
695 | rpc_set_running(task); | 680 | rpc_set_running(task); |
696 | dprintk("RPC: %5u sync task resuming\n", task->tk_pid); | 681 | dprintk("RPC: %5u sync task resuming\n", task->tk_pid); |
@@ -714,8 +699,9 @@ static void __rpc_execute(struct rpc_task *task) | |||
714 | void rpc_execute(struct rpc_task *task) | 699 | void rpc_execute(struct rpc_task *task) |
715 | { | 700 | { |
716 | rpc_set_active(task); | 701 | rpc_set_active(task); |
717 | rpc_set_running(task); | 702 | rpc_make_runnable(task); |
718 | __rpc_execute(task); | 703 | if (!RPC_IS_ASYNC(task)) |
704 | __rpc_execute(task); | ||
719 | } | 705 | } |
720 | 706 | ||
721 | static void rpc_async_schedule(struct work_struct *work) | 707 | static void rpc_async_schedule(struct work_struct *work) |
@@ -808,26 +794,9 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta | |||
808 | /* Initialize workqueue for async tasks */ | 794 | /* Initialize workqueue for async tasks */ |
809 | task->tk_workqueue = task_setup_data->workqueue; | 795 | task->tk_workqueue = task_setup_data->workqueue; |
810 | 796 | ||
811 | task->tk_client = task_setup_data->rpc_client; | ||
812 | if (task->tk_client != NULL) { | ||
813 | kref_get(&task->tk_client->cl_kref); | ||
814 | if (task->tk_client->cl_softrtry) | ||
815 | task->tk_flags |= RPC_TASK_SOFT; | ||
816 | } | ||
817 | |||
818 | if (task->tk_ops->rpc_call_prepare != NULL) | 797 | if (task->tk_ops->rpc_call_prepare != NULL) |
819 | task->tk_action = rpc_prepare_task; | 798 | task->tk_action = rpc_prepare_task; |
820 | 799 | ||
821 | if (task_setup_data->rpc_message != NULL) { | ||
822 | task->tk_msg.rpc_proc = task_setup_data->rpc_message->rpc_proc; | ||
823 | task->tk_msg.rpc_argp = task_setup_data->rpc_message->rpc_argp; | ||
824 | task->tk_msg.rpc_resp = task_setup_data->rpc_message->rpc_resp; | ||
825 | /* Bind the user cred */ | ||
826 | rpcauth_bindcred(task, task_setup_data->rpc_message->rpc_cred, task_setup_data->flags); | ||
827 | if (task->tk_action == NULL) | ||
828 | rpc_call_start(task); | ||
829 | } | ||
830 | |||
831 | /* starting timestamp */ | 800 | /* starting timestamp */ |
832 | task->tk_start = ktime_get(); | 801 | task->tk_start = ktime_get(); |
833 | 802 | ||
@@ -896,11 +865,8 @@ void rpc_put_task(struct rpc_task *task) | |||
896 | if (task->tk_rqstp) | 865 | if (task->tk_rqstp) |
897 | xprt_release(task); | 866 | xprt_release(task); |
898 | if (task->tk_msg.rpc_cred) | 867 | if (task->tk_msg.rpc_cred) |
899 | rpcauth_unbindcred(task); | 868 | put_rpccred(task->tk_msg.rpc_cred); |
900 | if (task->tk_client) { | 869 | rpc_task_release_client(task); |
901 | rpc_release_client(task->tk_client); | ||
902 | task->tk_client = NULL; | ||
903 | } | ||
904 | if (task->tk_workqueue != NULL) { | 870 | if (task->tk_workqueue != NULL) { |
905 | INIT_WORK(&task->u.tk_work, rpc_async_release); | 871 | INIT_WORK(&task->u.tk_work, rpc_async_release); |
906 | queue_work(task->tk_workqueue, &task->u.tk_work); | 872 | queue_work(task->tk_workqueue, &task->u.tk_work); |
@@ -913,13 +879,6 @@ static void rpc_release_task(struct rpc_task *task) | |||
913 | { | 879 | { |
914 | dprintk("RPC: %5u release task\n", task->tk_pid); | 880 | dprintk("RPC: %5u release task\n", task->tk_pid); |
915 | 881 | ||
916 | if (!list_empty(&task->tk_task)) { | ||
917 | struct rpc_clnt *clnt = task->tk_client; | ||
918 | /* Remove from client task list */ | ||
919 | spin_lock(&clnt->cl_lock); | ||
920 | list_del(&task->tk_task); | ||
921 | spin_unlock(&clnt->cl_lock); | ||
922 | } | ||
923 | BUG_ON (RPC_IS_QUEUED(task)); | 882 | BUG_ON (RPC_IS_QUEUED(task)); |
924 | 883 | ||
925 | /* Wake up anyone who is waiting for task completion */ | 884 | /* Wake up anyone who is waiting for task completion */ |
@@ -928,35 +887,6 @@ static void rpc_release_task(struct rpc_task *task) | |||
928 | rpc_put_task(task); | 887 | rpc_put_task(task); |
929 | } | 888 | } |
930 | 889 | ||
931 | /* | ||
932 | * Kill all tasks for the given client. | ||
933 | * XXX: kill their descendants as well? | ||
934 | */ | ||
935 | void rpc_killall_tasks(struct rpc_clnt *clnt) | ||
936 | { | ||
937 | struct rpc_task *rovr; | ||
938 | |||
939 | |||
940 | if (list_empty(&clnt->cl_tasks)) | ||
941 | return; | ||
942 | dprintk("RPC: killing all tasks for client %p\n", clnt); | ||
943 | /* | ||
944 | * Spin lock all_tasks to prevent changes... | ||
945 | */ | ||
946 | spin_lock(&clnt->cl_lock); | ||
947 | list_for_each_entry(rovr, &clnt->cl_tasks, tk_task) { | ||
948 | if (! RPC_IS_ACTIVATED(rovr)) | ||
949 | continue; | ||
950 | if (!(rovr->tk_flags & RPC_TASK_KILLED)) { | ||
951 | rovr->tk_flags |= RPC_TASK_KILLED; | ||
952 | rpc_exit(rovr, -EIO); | ||
953 | rpc_wake_up_task(rovr); | ||
954 | } | ||
955 | } | ||
956 | spin_unlock(&clnt->cl_lock); | ||
957 | } | ||
958 | EXPORT_SYMBOL_GPL(rpc_killall_tasks); | ||
959 | |||
960 | int rpciod_up(void) | 890 | int rpciod_up(void) |
961 | { | 891 | { |
962 | return try_module_get(THIS_MODULE) ? 0 : -EINVAL; | 892 | return try_module_get(THIS_MODULE) ? 0 : -EINVAL; |