[Devel,RHEL7,COMMIT] sunrpc: bring back SUNRPC task abort logic

Submitted by Konstantin Khorenko on June 27, 2017, 10:05 a.m.

Details

Message ID 201706271005.v5RA5s7a027503@finist_cl7.x64_64.work.ct
State New
Series "Kill SUNRPC tasks on container fast stop"
Headers show

Commit Message

Konstantin Khorenko June 27, 2017, 10:05 a.m.
The commit is pushed to "branch-rh7-3.10.0-514.16.1.vz7.32.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-514.16.1.vz7.32.11
------>
commit f79e44aaaa2b6e5a471638b7bc122aba1cfe334f
Author: Stanislav Kinsburskiy <skinsbursky@virtuozzo.com>
Date:   Tue Jun 27 14:05:54 2017 +0400

    sunrpc: bring back SUNRPC task abort logic
    
    We had this logic in vz6. But it was applied to any stop there.
    The intention was to solve 2 tasks:
    1) allow to stop container when network is unaccessible
    2) allow to suspend container with blocked network traffic.
    
    In vz7 we need the traffic to flow on suspend. Thus we have to distinguish
    between suspend (where the network must work) and "fast stop", when we
    want to kill container quickly (something similar to "reset" button).
    This dinstiguishment can be based on per-net SUNRPC "kill-tasks" attribute,
    which has to be set only in case of "fast stop".
    
    This solution allows us to mimic hardware behaviour closely. IOW, on normal
    stop (or migration) SUNRPC operates normally. But when user wants to stop it
    fast (i.e. he doesn't care about data, etc), then he can use "--fast" option
    and this patch comes into play.
    
    https://jira.sw.ru/browse/PSBM-66510
    
    Signed-off-by: Stanislav Kinsburskiy <skinsbursky@virtuozzo.com>
---
 include/linux/sunrpc/clnt.h |  2 ++
 net/sunrpc/clnt.c           | 14 ++++++++++++++
 net/sunrpc/sched.c          |  5 +++++
 3 files changed, 21 insertions(+)

Patch hide | download patch | download mbox

diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 597e5ae..75677554 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -186,5 +186,7 @@  const char *rpc_proc_name(const struct rpc_task *task);
 int rpc_task_kill_proc_init(struct net *net);
 void rpc_task_kill_proc_fini(struct net *net);
 
+bool rpc_abort_task(struct rpc_task *task);
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_SUNRPC_CLNT_H */
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index e64f751..2635c49 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -2607,3 +2607,17 @@  void rpc_task_kill_proc_fini(struct net *net)
 	if (sn->kill_tasks_proc)
 		remove_proc_entry("kill-tasks", sn->proc_net_rpc);
 }
+
+bool rpc_abort_task(struct rpc_task *task)
+{
+	struct net *net = rpc_net_ns(task->tk_client);
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+	if (!sn->kill_tasks)
+		return false;
+
+	dprintk("RPC: SUNRPC traffic is suppressed. Drop task %5u with EIO.\n",
+			task->tk_pid);
+
+	return true;
+}
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 16ada61..cd41946 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -728,6 +728,11 @@  static void __rpc_execute(struct rpc_task *task)
 	if (RPC_IS_QUEUED(task))
 		return;
 
+	if (rpc_abort_task(task)) {
+		task->tk_flags |= RPC_TASK_KILLED;
+		rpc_exit(task, -EIO);
+	}
+
 	for (;;) {
 		void (*do_action)(struct rpc_task *);