lockd: use svc_set_num_threads() for thread start and stop
authorNeilBrown <neilb@suse.de>
Mon, 29 Nov 2021 04:51:25 +0000 (15:51 +1100)
committerChuck Lever <chuck.lever@oracle.com>
Mon, 13 Dec 2021 18:42:58 +0000 (13:42 -0500)
svc_set_num_threads() does everything that lockd_start_svc() does, except
set sv_maxconn.  It also (when passed 0) finds the threads and
stops them with kthread_stop().

So move the setting for sv_maxconn, and use svc_set_num_thread()

We now don't need nlmsvc_task.

Now that we use svc_set_num_threads() it makes sense to set svo_module.
This request that the thread exists with module_put_and_exit().
Also fix the documentation for svo_module to make this explicit.

svc_prepare_thread is now only used where it is defined, so it can be
made static.

Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/lockd/svc.c
include/linux/sunrpc/svc.h
net/sunrpc/svc.c

index 1a7c111..4defefd 100644 (file)
@@ -55,7 +55,6 @@ EXPORT_SYMBOL_GPL(nlmsvc_ops);
 static DEFINE_MUTEX(nlmsvc_mutex);
 static unsigned int            nlmsvc_users;
 static struct svc_serv         *nlmsvc_serv;
-static struct task_struct      *nlmsvc_task;
 unsigned long                  nlmsvc_timeout;
 
 unsigned int lockd_net_id;
@@ -186,7 +185,7 @@ lockd(void *vrqstp)
 
        svc_exit_thread(rqstp);
 
-       return 0;
+       module_put_and_exit(0);
 }
 
 static int create_lockd_listener(struct svc_serv *serv, const char *name,
@@ -292,8 +291,8 @@ static void lockd_down_net(struct svc_serv *serv, struct net *net)
                                __func__, net->ns.inum);
                }
        } else {
-               pr_err("%s: no users! task=%p, net=%x\n",
-                       __func__, nlmsvc_task, net->ns.inum);
+               pr_err("%s: no users! net=%x\n",
+                       __func__, net->ns.inum);
                BUG();
        }
 }
@@ -351,49 +350,11 @@ static struct notifier_block lockd_inet6addr_notifier = {
 };
 #endif
 
-static int lockd_start_svc(struct svc_serv *serv)
-{
-       int error;
-       struct svc_rqst *rqst;
-
-       /*
-        * Create the kernel thread and wait for it to start.
-        */
-       rqst = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE);
-       if (IS_ERR(rqst)) {
-               error = PTR_ERR(rqst);
-               printk(KERN_WARNING
-                       "lockd_up: svc_rqst allocation failed, error=%d\n",
-                       error);
-               goto out_rqst;
-       }
-
-       svc_sock_update_bufs(serv);
-       serv->sv_maxconn = nlm_max_connections;
-
-       nlmsvc_task = kthread_create(lockd, rqst, "%s", serv->sv_name);
-       if (IS_ERR(nlmsvc_task)) {
-               error = PTR_ERR(nlmsvc_task);
-               printk(KERN_WARNING
-                       "lockd_up: kthread_run failed, error=%d\n", error);
-               goto out_task;
-       }
-       rqst->rq_task = nlmsvc_task;
-       wake_up_process(nlmsvc_task);
-
-       dprintk("lockd_up: service started\n");
-       return 0;
-
-out_task:
-       svc_exit_thread(rqst);
-       nlmsvc_task = NULL;
-out_rqst:
-       return error;
-}
-
 static const struct svc_serv_ops lockd_sv_ops = {
        .svo_shutdown           = svc_rpcb_cleanup,
+       .svo_function           = lockd,
        .svo_enqueue_xprt       = svc_xprt_do_enqueue,
+       .svo_module             = THIS_MODULE,
 };
 
 static int lockd_get(void)
@@ -425,7 +386,8 @@ static int lockd_get(void)
                return -ENOMEM;
        }
 
-       error = lockd_start_svc(serv);
+       serv->sv_maxconn = nlm_max_connections;
+       error = svc_set_num_threads(serv, NULL, 1);
        /* The thread now holds the only reference */
        svc_put(serv);
        if (error < 0)
@@ -453,11 +415,7 @@ static void lockd_put(void)
        unregister_inet6addr_notifier(&lockd_inet6addr_notifier);
 #endif
 
-       if (nlmsvc_task) {
-               kthread_stop(nlmsvc_task);
-               dprintk("lockd_down: service stopped\n");
-               nlmsvc_task = NULL;
-       }
+       svc_set_num_threads(nlmsvc_serv, NULL, 0);
        nlmsvc_serv = NULL;
        dprintk("lockd_down: service destroyed\n");
 }
index d69e610..cf175d4 100644 (file)
@@ -64,7 +64,9 @@ struct svc_serv_ops {
        /* queue up a transport for servicing */
        void            (*svo_enqueue_xprt)(struct svc_xprt *);
 
-       /* optional module to count when adding threads (pooled svcs only) */
+       /* optional module to count when adding threads.
+        * Thread function must call module_put_and_exit() to exit.
+        */
        struct module   *svo_module;
 };
 
@@ -504,8 +506,6 @@ struct svc_serv *svc_create(struct svc_program *, unsigned int,
                            const struct svc_serv_ops *);
 struct svc_rqst *svc_rqst_alloc(struct svc_serv *serv,
                                        struct svc_pool *pool, int node);
-struct svc_rqst *svc_prepare_thread(struct svc_serv *serv,
-                                       struct svc_pool *pool, int node);
 void              svc_rqst_replace_page(struct svc_rqst *rqstp,
                                         struct page *page);
 void              svc_rqst_free(struct svc_rqst *);
index 5fbe7f5..2aabec2 100644 (file)
@@ -652,7 +652,7 @@ out_enomem:
 }
 EXPORT_SYMBOL_GPL(svc_rqst_alloc);
 
-struct svc_rqst *
+static struct svc_rqst *
 svc_prepare_thread(struct svc_serv *serv, struct svc_pool *pool, int node)
 {
        struct svc_rqst *rqstp;
@@ -672,7 +672,6 @@ svc_prepare_thread(struct svc_serv *serv, struct svc_pool *pool, int node)
        spin_unlock_bh(&pool->sp_lock);
        return rqstp;
 }
-EXPORT_SYMBOL_GPL(svc_prepare_thread);
 
 /*
  * Choose a pool in which to create a new thread, for svc_set_num_threads