157 lines
4.5 KiB
Diff
157 lines
4.5 KiB
Diff
From 9e0d87680d689f1758185851c3da6eafb16e71e1 Mon Sep 17 00:00:00 2001
|
|
From: Trond Myklebust <trond.myklebust@primarydata.com>
|
|
Date: Wed, 26 Apr 2017 11:55:26 -0400
|
|
Subject: [PATCH] SUNRPC: Refactor svc_set_num_threads()
|
|
|
|
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 | 96 ++++++++++++++++++++++++++++++++++----------------------
|
|
1 file changed, 58 insertions(+), 38 deletions(-)
|
|
|
|
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
|
|
index a08aeb5..98dc33a 100644
|
|
--- a/net/sunrpc/svc.c
|
|
+++ b/net/sunrpc/svc.c
|
|
@@ -702,59 +702,32 @@ choose_victim(struct svc_serv *serv, struct svc_pool *pool, unsigned int *state)
|
|
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);
|
|
|
|
--
|
|
2.9.4
|
|
|