summaryrefslogtreecommitdiffstats
path: root/net/sunrpc/sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/sched.c')
-rw-r--r--net/sunrpc/sched.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 28956c70100a..3d6cb91ba598 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -759,8 +759,7 @@ static void
759rpc_reset_task_statistics(struct rpc_task *task) 759rpc_reset_task_statistics(struct rpc_task *task)
760{ 760{
761 task->tk_timeouts = 0; 761 task->tk_timeouts = 0;
762 task->tk_flags &= ~(RPC_CALL_MAJORSEEN|RPC_TASK_KILLED|RPC_TASK_SENT); 762 task->tk_flags &= ~(RPC_CALL_MAJORSEEN|RPC_TASK_SENT);
763
764 rpc_init_task_statistics(task); 763 rpc_init_task_statistics(task);
765} 764}
766 765
@@ -773,7 +772,6 @@ void rpc_exit_task(struct rpc_task *task)
773 if (task->tk_ops->rpc_call_done != NULL) { 772 if (task->tk_ops->rpc_call_done != NULL) {
774 task->tk_ops->rpc_call_done(task, task->tk_calldata); 773 task->tk_ops->rpc_call_done(task, task->tk_calldata);
775 if (task->tk_action != NULL) { 774 if (task->tk_action != NULL) {
776 WARN_ON(RPC_ASSASSINATED(task));
777 /* Always release the RPC slot and buffer memory */ 775 /* Always release the RPC slot and buffer memory */
778 xprt_release(task); 776 xprt_release(task);
779 rpc_reset_task_statistics(task); 777 rpc_reset_task_statistics(task);
@@ -781,6 +779,19 @@ void rpc_exit_task(struct rpc_task *task)
781 } 779 }
782} 780}
783 781
782void rpc_signal_task(struct rpc_task *task)
783{
784 struct rpc_wait_queue *queue;
785
786 if (!RPC_IS_ACTIVATED(task))
787 return;
788 set_bit(RPC_TASK_SIGNALLED, &task->tk_runstate);
789 smp_mb__after_atomic();
790 queue = READ_ONCE(task->tk_waitqueue);
791 if (queue)
792 rpc_wake_up_queued_task_set_status(queue, task, -ERESTARTSYS);
793}
794
784void rpc_exit(struct rpc_task *task, int status) 795void rpc_exit(struct rpc_task *task, int status)
785{ 796{
786 task->tk_status = status; 797 task->tk_status = status;
@@ -836,6 +847,13 @@ static void __rpc_execute(struct rpc_task *task)
836 */ 847 */
837 if (!RPC_IS_QUEUED(task)) 848 if (!RPC_IS_QUEUED(task))
838 continue; 849 continue;
850
851 /*
852 * Signalled tasks should exit rather than sleep.
853 */
854 if (RPC_SIGNALLED(task))
855 rpc_exit(task, -ERESTARTSYS);
856
839 /* 857 /*
840 * The queue->lock protects against races with 858 * The queue->lock protects against races with
841 * rpc_make_runnable(). 859 * rpc_make_runnable().
@@ -861,7 +879,7 @@ static void __rpc_execute(struct rpc_task *task)
861 status = out_of_line_wait_on_bit(&task->tk_runstate, 879 status = out_of_line_wait_on_bit(&task->tk_runstate,
862 RPC_TASK_QUEUED, rpc_wait_bit_killable, 880 RPC_TASK_QUEUED, rpc_wait_bit_killable,
863 TASK_KILLABLE); 881 TASK_KILLABLE);
864 if (status == -ERESTARTSYS) { 882 if (status < 0) {
865 /* 883 /*
866 * When a sync task receives a signal, it exits with 884 * When a sync task receives a signal, it exits with
867 * -ERESTARTSYS. In order to catch any callbacks that 885 * -ERESTARTSYS. In order to catch any callbacks that
@@ -869,7 +887,7 @@ static void __rpc_execute(struct rpc_task *task)
869 * break the loop here, but go around once more. 887 * break the loop here, but go around once more.
870 */ 888 */
871 dprintk("RPC: %5u got signal\n", task->tk_pid); 889 dprintk("RPC: %5u got signal\n", task->tk_pid);
872 task->tk_flags |= RPC_TASK_KILLED; 890 set_bit(RPC_TASK_SIGNALLED, &task->tk_runstate);
873 rpc_exit(task, -ERESTARTSYS); 891 rpc_exit(task, -ERESTARTSYS);
874 } 892 }
875 dprintk("RPC: %5u sync task resuming\n", task->tk_pid); 893 dprintk("RPC: %5u sync task resuming\n", task->tk_pid);