diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2016-08-29 20:03:51 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2016-09-19 13:08:36 -0400 |
commit | bb6aeba736ba9fd4d9569eec4bc3f7aecb42162a (patch) | |
tree | 2a2ceddf74b880b166462d2cfaa68470d6eebf9d | |
parent | 3b01c11ee8bfa9d5d14b028e9fbe861a0f22d328 (diff) |
NFSv4.x: Switch to using svc_set_num_threads() to manage the callback threads
This will allow us to bump the number of callback threads at will.
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r-- | fs/nfs/callback.c | 79 | ||||
-rw-r--r-- | fs/nfs/callback.h | 2 |
2 files changed, 15 insertions, 66 deletions
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index b125f02ddf8b..b91c49f4670b 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c | |||
@@ -31,8 +31,6 @@ | |||
31 | struct nfs_callback_data { | 31 | struct nfs_callback_data { |
32 | unsigned int users; | 32 | unsigned int users; |
33 | struct svc_serv *serv; | 33 | struct svc_serv *serv; |
34 | struct svc_rqst *rqst; | ||
35 | struct task_struct *task; | ||
36 | }; | 34 | }; |
37 | 35 | ||
38 | static struct nfs_callback_data nfs_callback_info[NFS4_MAX_MINOR_VERSION + 1]; | 36 | static struct nfs_callback_data nfs_callback_info[NFS4_MAX_MINOR_VERSION + 1]; |
@@ -89,15 +87,6 @@ nfs4_callback_svc(void *vrqstp) | |||
89 | return 0; | 87 | return 0; |
90 | } | 88 | } |
91 | 89 | ||
92 | /* | ||
93 | * Prepare to bring up the NFSv4 callback service | ||
94 | */ | ||
95 | static struct svc_rqst * | ||
96 | nfs4_callback_up(struct svc_serv *serv) | ||
97 | { | ||
98 | return svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE); | ||
99 | } | ||
100 | |||
101 | #if defined(CONFIG_NFS_V4_1) | 90 | #if defined(CONFIG_NFS_V4_1) |
102 | /* | 91 | /* |
103 | * The callback service for NFSv4.1 callbacks | 92 | * The callback service for NFSv4.1 callbacks |
@@ -139,19 +128,6 @@ nfs41_callback_svc(void *vrqstp) | |||
139 | return 0; | 128 | return 0; |
140 | } | 129 | } |
141 | 130 | ||
142 | /* | ||
143 | * Bring up the NFSv4.1 callback service | ||
144 | */ | ||
145 | static struct svc_rqst * | ||
146 | nfs41_callback_up(struct svc_serv *serv) | ||
147 | { | ||
148 | struct svc_rqst *rqstp; | ||
149 | |||
150 | rqstp = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE); | ||
151 | dprintk("--> %s return %d\n", __func__, PTR_ERR_OR_ZERO(rqstp)); | ||
152 | return rqstp; | ||
153 | } | ||
154 | |||
155 | static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, | 131 | static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, |
156 | struct svc_serv *serv) | 132 | struct svc_serv *serv) |
157 | { | 133 | { |
@@ -163,12 +139,6 @@ static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, | |||
163 | xprt->bc_serv = serv; | 139 | xprt->bc_serv = serv; |
164 | } | 140 | } |
165 | #else | 141 | #else |
166 | static struct svc_rqst * | ||
167 | nfs41_callback_up(struct svc_serv *serv) | ||
168 | { | ||
169 | return ERR_PTR(-ENOTSUPP); | ||
170 | } | ||
171 | |||
172 | static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, | 142 | static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, |
173 | struct svc_serv *serv) | 143 | struct svc_serv *serv) |
174 | { | 144 | { |
@@ -178,42 +148,19 @@ static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, | |||
178 | static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt, | 148 | static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt, |
179 | struct svc_serv *serv) | 149 | struct svc_serv *serv) |
180 | { | 150 | { |
181 | struct svc_rqst *rqstp; | 151 | const int nrservs = NFS4_NR_CALLBACK_THREADS; |
182 | struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; | ||
183 | int ret; | 152 | int ret; |
184 | 153 | ||
185 | nfs_callback_bc_serv(minorversion, xprt, serv); | 154 | nfs_callback_bc_serv(minorversion, xprt, serv); |
186 | 155 | ||
187 | if (cb_info->task) | 156 | if (serv->sv_nrthreads-1 == nrservs) |
188 | return 0; | 157 | return 0; |
189 | 158 | ||
190 | switch (minorversion) { | 159 | ret = serv->sv_ops->svo_setup(serv, NULL, nrservs); |
191 | case 0: | 160 | if (ret) { |
192 | /* v4.0 callback setup */ | 161 | serv->sv_ops->svo_setup(serv, NULL, 0); |
193 | rqstp = nfs4_callback_up(serv); | ||
194 | break; | ||
195 | default: | ||
196 | rqstp = nfs41_callback_up(serv); | ||
197 | } | ||
198 | |||
199 | if (IS_ERR(rqstp)) | ||
200 | return PTR_ERR(rqstp); | ||
201 | |||
202 | svc_sock_update_bufs(serv); | ||
203 | |||
204 | cb_info->rqst = rqstp; | ||
205 | cb_info->task = kthread_create(serv->sv_ops->svo_function, | ||
206 | cb_info->rqst, | ||
207 | "nfsv4.%u-svc", minorversion); | ||
208 | if (IS_ERR(cb_info->task)) { | ||
209 | ret = PTR_ERR(cb_info->task); | ||
210 | svc_exit_thread(cb_info->rqst); | ||
211 | cb_info->rqst = NULL; | ||
212 | cb_info->task = NULL; | ||
213 | return ret; | 162 | return ret; |
214 | } | 163 | } |
215 | rqstp->rq_task = cb_info->task; | ||
216 | wake_up_process(cb_info->task); | ||
217 | dprintk("nfs_callback_up: service started\n"); | 164 | dprintk("nfs_callback_up: service started\n"); |
218 | return 0; | 165 | return 0; |
219 | } | 166 | } |
@@ -270,12 +217,14 @@ err_bind: | |||
270 | static struct svc_serv_ops nfs40_cb_sv_ops = { | 217 | static struct svc_serv_ops nfs40_cb_sv_ops = { |
271 | .svo_function = nfs4_callback_svc, | 218 | .svo_function = nfs4_callback_svc, |
272 | .svo_enqueue_xprt = svc_xprt_do_enqueue, | 219 | .svo_enqueue_xprt = svc_xprt_do_enqueue, |
220 | .svo_setup = svc_set_num_threads, | ||
273 | .svo_module = THIS_MODULE, | 221 | .svo_module = THIS_MODULE, |
274 | }; | 222 | }; |
275 | #if defined(CONFIG_NFS_V4_1) | 223 | #if defined(CONFIG_NFS_V4_1) |
276 | static struct svc_serv_ops nfs41_cb_sv_ops = { | 224 | static struct svc_serv_ops nfs41_cb_sv_ops = { |
277 | .svo_function = nfs41_callback_svc, | 225 | .svo_function = nfs41_callback_svc, |
278 | .svo_enqueue_xprt = svc_xprt_do_enqueue, | 226 | .svo_enqueue_xprt = svc_xprt_do_enqueue, |
227 | .svo_setup = svc_set_num_threads, | ||
279 | .svo_module = THIS_MODULE, | 228 | .svo_module = THIS_MODULE, |
280 | }; | 229 | }; |
281 | 230 | ||
@@ -394,20 +343,18 @@ err_start: | |||
394 | void nfs_callback_down(int minorversion, struct net *net) | 343 | void nfs_callback_down(int minorversion, struct net *net) |
395 | { | 344 | { |
396 | struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; | 345 | struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; |
346 | struct svc_serv *serv; | ||
397 | 347 | ||
398 | mutex_lock(&nfs_callback_mutex); | 348 | mutex_lock(&nfs_callback_mutex); |
399 | nfs_callback_down_net(minorversion, cb_info->serv, net); | 349 | serv = cb_info->serv; |
350 | nfs_callback_down_net(minorversion, serv, net); | ||
400 | cb_info->users--; | 351 | cb_info->users--; |
401 | if (cb_info->users == 0) { | 352 | if (cb_info->users == 0) { |
402 | if (cb_info->task != NULL) { | 353 | svc_get(serv); |
403 | kthread_stop(cb_info->task); | 354 | serv->sv_ops->svo_setup(serv, NULL, 0); |
404 | dprintk("nfs_callback_down: service stopped\n"); | 355 | svc_destroy(serv); |
405 | } | ||
406 | svc_exit_thread(cb_info->rqst); | ||
407 | dprintk("nfs_callback_down: service destroyed\n"); | 356 | dprintk("nfs_callback_down: service destroyed\n"); |
408 | cb_info->serv = NULL; | 357 | cb_info->serv = NULL; |
409 | cb_info->rqst = NULL; | ||
410 | cb_info->task = NULL; | ||
411 | } | 358 | } |
412 | mutex_unlock(&nfs_callback_mutex); | 359 | mutex_unlock(&nfs_callback_mutex); |
413 | } | 360 | } |
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h index 5fe1cecbf9f0..14bd863495db 100644 --- a/fs/nfs/callback.h +++ b/fs/nfs/callback.h | |||
@@ -198,6 +198,8 @@ extern void nfs_callback_down(int minorversion, struct net *net); | |||
198 | #define NFS41_BC_MIN_CALLBACKS 1 | 198 | #define NFS41_BC_MIN_CALLBACKS 1 |
199 | #define NFS41_BC_MAX_CALLBACKS 1 | 199 | #define NFS41_BC_MAX_CALLBACKS 1 |
200 | 200 | ||
201 | #define NFS4_NR_CALLBACK_THREADS 1 | ||
202 | |||
201 | extern unsigned int nfs_callback_set_tcpport; | 203 | extern unsigned int nfs_callback_set_tcpport; |
202 | 204 | ||
203 | #endif /* __LINUX_FS_NFS_CALLBACK_H */ | 205 | #endif /* __LINUX_FS_NFS_CALLBACK_H */ |