SUNRPC: Refactor svc_set_num_threads()
authorTrond Myklebust <trond.myklebust@primarydata.com>
Wed, 26 Apr 2017 15:55:26 +0000 (11:55 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Thu, 27 Apr 2017 21:59:58 +0000 (17:59 -0400)
Refactor to separate out the functions of starting and stopping threads
so that they can be used in other helpers.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Tested-and-reviewed-by: Kinglong Mee <kinglongmee@gmail.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
net/sunrpc/svc.c

index a08aeb56b8e457d56285558048e4a41ab00b03c9..98dc33ae738b94c840d43619e099e845bd589c20 100644 (file)
@@ -702,59 +702,32 @@ found_pool:
        return task;
 }
 
-/*
- * Create or destroy enough new threads to make the number
- * of threads the given number.  If `pool' is non-NULL, applies
- * only to threads in that pool, otherwise round-robins between
- * all pools.  Caller must ensure that mutual exclusion between this and
- * server startup or shutdown.
- *
- * Destroying threads relies on the service threads filling in
- * rqstp->rq_task, which only the nfs ones do.  Assumes the serv
- * has been created using svc_create_pooled().
- *
- * Based on code that used to be in nfsd_svc() but tweaked
- * to be pool-aware.
- */
-int
-svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
+/* create new threads */
+static int
+svc_start_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
 {
        struct svc_rqst *rqstp;
        struct task_struct *task;
        struct svc_pool *chosen_pool;
-       int error = 0;
        unsigned int state = serv->sv_nrthreads-1;
        int node;
 
-       if (pool == NULL) {
-               /* The -1 assumes caller has done a svc_get() */
-               nrservs -= (serv->sv_nrthreads-1);
-       } else {
-               spin_lock_bh(&pool->sp_lock);
-               nrservs -= pool->sp_nrthreads;
-               spin_unlock_bh(&pool->sp_lock);
-       }
-
-       /* create new threads */
-       while (nrservs > 0) {
+       do {
                nrservs--;
                chosen_pool = choose_pool(serv, pool, &state);
 
                node = svc_pool_map_get_node(chosen_pool->sp_id);
                rqstp = svc_prepare_thread(serv, chosen_pool, node);
-               if (IS_ERR(rqstp)) {
-                       error = PTR_ERR(rqstp);
-                       break;
-               }
+               if (IS_ERR(rqstp))
+                       return PTR_ERR(rqstp);
 
                __module_get(serv->sv_ops->svo_module);
                task = kthread_create_on_node(serv->sv_ops->svo_function, rqstp,
                                              node, "%s", serv->sv_name);
                if (IS_ERR(task)) {
-                       error = PTR_ERR(task);
                        module_put(serv->sv_ops->svo_module);
                        svc_exit_thread(rqstp);
-                       break;
+                       return PTR_ERR(task);
                }
 
                rqstp->rq_task = task;
@@ -763,15 +736,62 @@ svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
 
                svc_sock_update_bufs(serv);
                wake_up_process(task);
-       }
+       } while (nrservs > 0);
+
+       return 0;
+}
+
+
+/* destroy old threads */
+static int
+svc_signal_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
+{
+       struct task_struct *task;
+       unsigned int state = serv->sv_nrthreads-1;
+
        /* destroy old threads */
-       while (nrservs < 0 &&
-              (task = choose_victim(serv, pool, &state)) != NULL) {
+       do {
+               task = choose_victim(serv, pool, &state);
+               if (task == NULL)
+                       break;
                send_sig(SIGINT, task, 1);
                nrservs++;
+       } while (nrservs < 0);
+
+       return 0;
+}
+
+/*
+ * Create or destroy enough new threads to make the number
+ * of threads the given number.  If `pool' is non-NULL, applies
+ * only to threads in that pool, otherwise round-robins between
+ * all pools.  Caller must ensure that mutual exclusion between this and
+ * server startup or shutdown.
+ *
+ * Destroying threads relies on the service threads filling in
+ * rqstp->rq_task, which only the nfs ones do.  Assumes the serv
+ * has been created using svc_create_pooled().
+ *
+ * Based on code that used to be in nfsd_svc() but tweaked
+ * to be pool-aware.
+ */
+int
+svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
+{
+       if (pool == NULL) {
+               /* The -1 assumes caller has done a svc_get() */
+               nrservs -= (serv->sv_nrthreads-1);
+       } else {
+               spin_lock_bh(&pool->sp_lock);
+               nrservs -= pool->sp_nrthreads;
+               spin_unlock_bh(&pool->sp_lock);
        }
 
-       return error;
+       if (nrservs > 0)
+               return svc_start_kthreads(serv, pool, nrservs);
+       if (nrservs < 0)
+               return svc_signal_kthreads(serv, pool, nrservs);
+       return 0;
 }
 EXPORT_SYMBOL_GPL(svc_set_num_threads);