Commit 58f9612c6ea858f532021a0ce42ec53cb0a493b3
1 parent
d9b6cd9460
Exists in
master
and in
7 other branches
SUNRPC: Move remaining RPC client related task initialisation into clnt.c
Now that rpc_run_task() is the sole entry point for RPC calls, we can move the remaining rpc_client-related initialisation of struct rpc_task from sched.c into clnt.c. Also move rpc_killall_tasks() into the same file, since that too is relative to the rpc_clnt. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Showing 3 changed files with 89 additions and 73 deletions Side-by-side Diff
include/linux/sunrpc/clnt.h
... | ... | @@ -131,6 +131,7 @@ |
131 | 131 | struct rpc_clnt *rpc_clone_client(struct rpc_clnt *); |
132 | 132 | void rpc_shutdown_client(struct rpc_clnt *); |
133 | 133 | void rpc_release_client(struct rpc_clnt *); |
134 | +void rpc_task_release_client(struct rpc_task *); | |
134 | 135 | |
135 | 136 | int rpcb_register(u32, u32, int, unsigned short); |
136 | 137 | int rpcb_v4_register(const u32 program, const u32 version, |
net/sunrpc/clnt.c
... | ... | @@ -414,6 +414,35 @@ |
414 | 414 | EXPORT_SYMBOL_GPL(rpc_clone_client); |
415 | 415 | |
416 | 416 | /* |
417 | + * Kill all tasks for the given client. | |
418 | + * XXX: kill their descendants as well? | |
419 | + */ | |
420 | +void rpc_killall_tasks(struct rpc_clnt *clnt) | |
421 | +{ | |
422 | + struct rpc_task *rovr; | |
423 | + | |
424 | + | |
425 | + if (list_empty(&clnt->cl_tasks)) | |
426 | + return; | |
427 | + dprintk("RPC: killing all tasks for client %p\n", clnt); | |
428 | + /* | |
429 | + * Spin lock all_tasks to prevent changes... | |
430 | + */ | |
431 | + spin_lock(&clnt->cl_lock); | |
432 | + list_for_each_entry(rovr, &clnt->cl_tasks, tk_task) { | |
433 | + if (!RPC_IS_ACTIVATED(rovr)) | |
434 | + continue; | |
435 | + if (!(rovr->tk_flags & RPC_TASK_KILLED)) { | |
436 | + rovr->tk_flags |= RPC_TASK_KILLED; | |
437 | + rpc_exit(rovr, -EIO); | |
438 | + rpc_wake_up_queued_task(rovr->tk_waitqueue, rovr); | |
439 | + } | |
440 | + } | |
441 | + spin_unlock(&clnt->cl_lock); | |
442 | +} | |
443 | +EXPORT_SYMBOL_GPL(rpc_killall_tasks); | |
444 | + | |
445 | +/* | |
417 | 446 | * Properly shut down an RPC client, terminating all outstanding |
418 | 447 | * requests. |
419 | 448 | */ |
... | ... | @@ -538,6 +567,49 @@ |
538 | 567 | } |
539 | 568 | EXPORT_SYMBOL_GPL(rpc_bind_new_program); |
540 | 569 | |
570 | +void rpc_task_release_client(struct rpc_task *task) | |
571 | +{ | |
572 | + struct rpc_clnt *clnt = task->tk_client; | |
573 | + | |
574 | + if (clnt != NULL) { | |
575 | + /* Remove from client task list */ | |
576 | + spin_lock(&clnt->cl_lock); | |
577 | + list_del(&task->tk_task); | |
578 | + spin_unlock(&clnt->cl_lock); | |
579 | + task->tk_client = NULL; | |
580 | + | |
581 | + rpc_release_client(clnt); | |
582 | + } | |
583 | +} | |
584 | + | |
585 | +static | |
586 | +void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt) | |
587 | +{ | |
588 | + if (clnt != NULL) { | |
589 | + rpc_task_release_client(task); | |
590 | + task->tk_client = clnt; | |
591 | + kref_get(&clnt->cl_kref); | |
592 | + if (clnt->cl_softrtry) | |
593 | + task->tk_flags |= RPC_TASK_SOFT; | |
594 | + /* Add to the client's list of all tasks */ | |
595 | + spin_lock(&clnt->cl_lock); | |
596 | + list_add_tail(&task->tk_task, &clnt->cl_tasks); | |
597 | + spin_unlock(&clnt->cl_lock); | |
598 | + } | |
599 | +} | |
600 | + | |
601 | +static void | |
602 | +rpc_task_set_rpc_message(struct rpc_task *task, const struct rpc_message *msg) | |
603 | +{ | |
604 | + if (msg != NULL) { | |
605 | + task->tk_msg.rpc_proc = msg->rpc_proc; | |
606 | + task->tk_msg.rpc_argp = msg->rpc_argp; | |
607 | + task->tk_msg.rpc_resp = msg->rpc_resp; | |
608 | + /* Bind the user cred */ | |
609 | + rpcauth_bindcred(task, msg->rpc_cred, task->tk_flags); | |
610 | + } | |
611 | +} | |
612 | + | |
541 | 613 | /* |
542 | 614 | * Default callback for async RPC calls |
543 | 615 | */ |
... | ... | @@ -561,6 +633,18 @@ |
561 | 633 | task = rpc_new_task(task_setup_data); |
562 | 634 | if (IS_ERR(task)) |
563 | 635 | goto out; |
636 | + | |
637 | + rpc_task_set_client(task, task_setup_data->rpc_client); | |
638 | + rpc_task_set_rpc_message(task, task_setup_data->rpc_message); | |
639 | + | |
640 | + if (task->tk_status != 0) { | |
641 | + int ret = task->tk_status; | |
642 | + rpc_put_task(task); | |
643 | + return ERR_PTR(ret); | |
644 | + } | |
645 | + | |
646 | + if (task->tk_action == NULL) | |
647 | + rpc_call_start(task); | |
564 | 648 | |
565 | 649 | atomic_inc(&task->tk_count); |
566 | 650 | rpc_execute(task); |
net/sunrpc/sched.c
... | ... | @@ -246,17 +246,8 @@ |
246 | 246 | |
247 | 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 | 249 | rpc_task_set_debuginfo(task); |
253 | - /* Add to global list of all tasks */ | |
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 | - } | |
250 | + set_bit(RPC_TASK_ACTIVE, &task->tk_runstate); | |
260 | 251 | } |
261 | 252 | |
262 | 253 | /* |
... | ... | @@ -319,11 +310,6 @@ |
319 | 310 | dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n", |
320 | 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 | 313 | __rpc_add_wait_queue(q, task); |
328 | 314 | |
329 | 315 | BUG_ON(task->tk_callback != NULL); |
... | ... | @@ -334,8 +320,8 @@ |
334 | 320 | void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, |
335 | 321 | rpc_action action) |
336 | 322 | { |
337 | - /* Mark the task as being activated if so needed */ | |
338 | - rpc_set_active(task); | |
323 | + /* We shouldn't ever put an inactive task to sleep */ | |
324 | + BUG_ON(!RPC_IS_ACTIVATED(task)); | |
339 | 325 | |
340 | 326 | /* |
341 | 327 | * Protect the queue operations. |
342 | 328 | |
... | ... | @@ -807,26 +793,9 @@ |
807 | 793 | /* Initialize workqueue for async tasks */ |
808 | 794 | task->tk_workqueue = task_setup_data->workqueue; |
809 | 795 | |
810 | - task->tk_client = task_setup_data->rpc_client; | |
811 | - if (task->tk_client != NULL) { | |
812 | - kref_get(&task->tk_client->cl_kref); | |
813 | - if (task->tk_client->cl_softrtry) | |
814 | - task->tk_flags |= RPC_TASK_SOFT; | |
815 | - } | |
816 | - | |
817 | 796 | if (task->tk_ops->rpc_call_prepare != NULL) |
818 | 797 | task->tk_action = rpc_prepare_task; |
819 | 798 | |
820 | - if (task_setup_data->rpc_message != NULL) { | |
821 | - task->tk_msg.rpc_proc = task_setup_data->rpc_message->rpc_proc; | |
822 | - task->tk_msg.rpc_argp = task_setup_data->rpc_message->rpc_argp; | |
823 | - task->tk_msg.rpc_resp = task_setup_data->rpc_message->rpc_resp; | |
824 | - /* Bind the user cred */ | |
825 | - rpcauth_bindcred(task, task_setup_data->rpc_message->rpc_cred, task_setup_data->flags); | |
826 | - if (task->tk_action == NULL) | |
827 | - rpc_call_start(task); | |
828 | - } | |
829 | - | |
830 | 799 | /* starting timestamp */ |
831 | 800 | task->tk_start = ktime_get(); |
832 | 801 | |
... | ... | @@ -896,10 +865,7 @@ |
896 | 865 | xprt_release(task); |
897 | 866 | if (task->tk_msg.rpc_cred) |
898 | 867 | rpcauth_unbindcred(task); |
899 | - if (task->tk_client) { | |
900 | - rpc_release_client(task->tk_client); | |
901 | - task->tk_client = NULL; | |
902 | - } | |
868 | + rpc_task_release_client(task); | |
903 | 869 | if (task->tk_workqueue != NULL) { |
904 | 870 | INIT_WORK(&task->u.tk_work, rpc_async_release); |
905 | 871 | queue_work(task->tk_workqueue, &task->u.tk_work); |
... | ... | @@ -912,13 +878,6 @@ |
912 | 878 | { |
913 | 879 | dprintk("RPC: %5u release task\n", task->tk_pid); |
914 | 880 | |
915 | - if (!list_empty(&task->tk_task)) { | |
916 | - struct rpc_clnt *clnt = task->tk_client; | |
917 | - /* Remove from client task list */ | |
918 | - spin_lock(&clnt->cl_lock); | |
919 | - list_del(&task->tk_task); | |
920 | - spin_unlock(&clnt->cl_lock); | |
921 | - } | |
922 | 881 | BUG_ON (RPC_IS_QUEUED(task)); |
923 | 882 | |
924 | 883 | /* Wake up anyone who is waiting for task completion */ |
... | ... | @@ -926,34 +885,6 @@ |
926 | 885 | |
927 | 886 | rpc_put_task(task); |
928 | 887 | } |
929 | - | |
930 | -/* | |
931 | - * Kill all tasks for the given client. | |
932 | - * XXX: kill their descendants as well? | |
933 | - */ | |
934 | -void rpc_killall_tasks(struct rpc_clnt *clnt) | |
935 | -{ | |
936 | - struct rpc_task *rovr; | |
937 | - | |
938 | - | |
939 | - if (list_empty(&clnt->cl_tasks)) | |
940 | - return; | |
941 | - dprintk("RPC: killing all tasks for client %p\n", clnt); | |
942 | - /* | |
943 | - * Spin lock all_tasks to prevent changes... | |
944 | - */ | |
945 | - spin_lock(&clnt->cl_lock); | |
946 | - list_for_each_entry(rovr, &clnt->cl_tasks, tk_task) { | |
947 | - if (! RPC_IS_ACTIVATED(rovr)) | |
948 | - continue; | |
949 | - if (!(rovr->tk_flags & RPC_TASK_KILLED)) { | |
950 | - rovr->tk_flags |= RPC_TASK_KILLED; | |
951 | - rpc_exit(rovr, -EIO); | |
952 | - } | |
953 | - } | |
954 | - spin_unlock(&clnt->cl_lock); | |
955 | -} | |
956 | -EXPORT_SYMBOL_GPL(rpc_killall_tasks); | |
957 | 888 | |
958 | 889 | int rpciod_up(void) |
959 | 890 | { |