[Devel] [PATCH RHEL9 COMMIT] ve/sunrpc/nfs: do not containerize nfs svc callback kthreads

Konstantin Khorenko khorenko at virtuozzo.com
Fri Nov 19 18:54:42 MSK 2021


The commit is pushed to "branch-rh9-5.14.vz9.1.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh9-5.14.0-4.vz9.10.30
------>
commit 2d18d37a5d593a36e7044fcf6901c58e8aabf4d5
Author: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
Date:   Fri Nov 19 18:54:42 2021 +0300

    ve/sunrpc/nfs: do not containerize nfs svc callback kthreads
    
    After rebasing our ve-nfs code on top of [1], which appeared in RH8,
    nfs41_callback_svc's kthread mistakenly was started from ve, which called
    nfs mount, due to our commit [2] (which was originally designed to put
    only nfsd callback kthreads into ve), because after [1] all callback
    kthreads are now created via the same code.
    
    Original problem with this kthread was that on ve stop this kthread was
    not stopping while beeing in the process tree of ve, so ve init waited
    for this kthread infinitely leading to ve suspend/stop hang forever.
    
    Looking on nfs_callback_up, we can see that serv returned by
    nfs_callback_create_svc is global nfs_callback_info[minorversion].serv
    variable, meaning that in nfs_callback_start_svc we create maximum
    nrservs kthreads for all host (see serv->sv_nrthreads check).
    
    Meaning that all containers and host reuse same svc callback kthreads.
    So this kthread can be serving nfs mounts from host or from different
    containers so it logically should not stop along with ve stop. So it
    just should not be in ve.
    
    Looking on nfsd_set_nrthreads we can see that nfsd on the contrary
    creates own kthreads per-net, so they can safely be created in ve.
    
    So we must act differently for nfsd and nfs callback kthreads, for nfsd
    we can create kthreads inside ve, but for nfs we can not do this. So
    let's mark svc_serv with special ve_virtualized flag to indicate if we
    need to create the kthread in ve or not.
    
    https://jira.sw.ru/browse/PSBM-135334
    Related-to: bb6aeba736ba ("NFSv4.x: Switch to using
    svc_set_num_threads() to manage the callback threads") [1]
    Fixes: 00755c421f82 ("ve/sunrpc/nfsd: containerize kthreads") [2]
    Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
 fs/nfsd/nfssvc.c           |  1 +
 include/linux/sunrpc/svc.h |  1 +
 net/sunrpc/svc.c           | 13 +++++++++----
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index ccb59e91011b..6de28796a941 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -651,6 +651,7 @@ int nfsd_create_serv(struct net *net)
 						&nfsd_thread_sv_ops);
 	if (nn->nfsd_serv == NULL)
 		return -ENOMEM;
+	nn->nfsd_serv->ve_virtualized = true;
 	init_completion(&nn->nfsd_shutdown_complete);
 
 	nn->nfsd_serv->sv_maxconn = nn->max_connections;
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index e91d51ea028b..7c60cfee765d 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -111,6 +111,7 @@ struct svc_serv {
 						 * entries in the svc_cb_list */
 	bool			sv_bc_enabled;	/* service uses backchannel */
 #endif /* CONFIG_SUNRPC_BACKCHANNEL */
+	bool			ve_virtualized;	/* kthreads start in ve */
 };
 
 /*
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index bf0eedd21974..89b3293f6b52 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -728,10 +728,15 @@ svc_start_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
 			return PTR_ERR(rqstp);
 
 		__module_get(serv->sv_ops->svo_module);
-		task = kthread_create_on_node_ve_flags(get_exec_env(), 0,
-						 serv->sv_ops->svo_function,
-						 rqstp, node,
-						 "%s", serv->sv_name);
+		if (serv->ve_virtualized) {
+			task = kthread_create_on_node_ve_flags(get_exec_env(),
+					0, serv->sv_ops->svo_function, rqstp,
+					node, "%s", serv->sv_name);
+		} else {
+			task = kthread_create_on_node(
+					serv->sv_ops->svo_function, rqstp,
+					node, "%s", serv->sv_name);
+		}
 		if (IS_ERR(task)) {
 			module_put(serv->sv_ops->svo_module);
 			svc_exit_thread(rqstp);


More information about the Devel mailing list