From d9f9b83539ab9b1ebb5cbdfa0a5a9994e20e6a0d Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 26 Apr 2017 11:55:26 -0400 Subject: [PATCH] SUNRPC: Refactor svc_set_num_threads() commit 9e0d87680d689f1758185851c3da6eafb16e71e1 upstream. 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 Tested-and-reviewed-by: Kinglong Mee Signed-off-by: J. Bruce Fields Cc: Jan Hudoba Signed-off-by: Greg Kroah-Hartman --- net/sunrpc/svc.c | 108 ++++++++++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 44 deletions(-) diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 75f290bddca1..70c9040ed7f7 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -702,6 +702,65 @@ found_pool: return task; } +/* 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; + unsigned int state = serv->sv_nrthreads-1; + int node; + + 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)) + 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)) { + module_put(serv->sv_ops->svo_module); + svc_exit_thread(rqstp); + return PTR_ERR(task); + } + + rqstp->rq_task = task; + if (serv->sv_nrpools > 1) + svc_pool_map_set_cpumask(task, chosen_pool->sp_id); + + 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 */ + 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 @@ -719,13 +778,6 @@ found_pool: int svc_set_num_threads(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); @@ -735,43 +787,11 @@ svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs) spin_unlock_bh(&pool->sp_lock); } - /* create new threads */ - while (nrservs > 0) { - 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; - } - - __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; - } - - rqstp->rq_task = task; - if (serv->sv_nrpools > 1) - svc_pool_map_set_cpumask(task, chosen_pool->sp_id); - - svc_sock_update_bufs(serv); - wake_up_process(task); - } - /* destroy old threads */ - while (nrservs < 0 && - (task = choose_victim(serv, pool, &state)) != NULL) { - send_sig(SIGINT, task, 1); - nrservs++; - } - - 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);