aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svc.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/svc.c')
-rw-r--r--net/sunrpc/svc.c56
1 files changed, 49 insertions, 7 deletions
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 0c2c52276285..6750cd474f84 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -32,6 +32,7 @@ svc_create(struct svc_program *prog, unsigned int bufsize,
32 struct svc_serv *serv; 32 struct svc_serv *serv;
33 int vers; 33 int vers;
34 unsigned int xdrsize; 34 unsigned int xdrsize;
35 unsigned int i;
35 36
36 if (!(serv = kzalloc(sizeof(*serv), GFP_KERNEL))) 37 if (!(serv = kzalloc(sizeof(*serv), GFP_KERNEL)))
37 return NULL; 38 return NULL;
@@ -55,13 +56,33 @@ svc_create(struct svc_program *prog, unsigned int bufsize,
55 prog = prog->pg_next; 56 prog = prog->pg_next;
56 } 57 }
57 serv->sv_xdrsize = xdrsize; 58 serv->sv_xdrsize = xdrsize;
58 INIT_LIST_HEAD(&serv->sv_threads);
59 INIT_LIST_HEAD(&serv->sv_sockets);
60 INIT_LIST_HEAD(&serv->sv_tempsocks); 59 INIT_LIST_HEAD(&serv->sv_tempsocks);
61 INIT_LIST_HEAD(&serv->sv_permsocks); 60 INIT_LIST_HEAD(&serv->sv_permsocks);
62 init_timer(&serv->sv_temptimer); 61 init_timer(&serv->sv_temptimer);
63 spin_lock_init(&serv->sv_lock); 62 spin_lock_init(&serv->sv_lock);
64 63
64 serv->sv_nrpools = 1;
65 serv->sv_pools =
66 kcalloc(sizeof(struct svc_pool), serv->sv_nrpools,
67 GFP_KERNEL);
68 if (!serv->sv_pools) {
69 kfree(serv);
70 return NULL;
71 }
72
73 for (i = 0; i < serv->sv_nrpools; i++) {
74 struct svc_pool *pool = &serv->sv_pools[i];
75
76 dprintk("initialising pool %u for %s\n",
77 i, serv->sv_name);
78
79 pool->sp_id = i;
80 INIT_LIST_HEAD(&pool->sp_threads);
81 INIT_LIST_HEAD(&pool->sp_sockets);
82 spin_lock_init(&pool->sp_lock);
83 }
84
85
65 /* Remove any stale portmap registrations */ 86 /* Remove any stale portmap registrations */
66 svc_register(serv, 0, 0); 87 svc_register(serv, 0, 0);
67 88
@@ -69,7 +90,7 @@ svc_create(struct svc_program *prog, unsigned int bufsize,
69} 90}
70 91
71/* 92/*
72 * Destroy an RPC service 93 * Destroy an RPC service. Should be called with the BKL held
73 */ 94 */
74void 95void
75svc_destroy(struct svc_serv *serv) 96svc_destroy(struct svc_serv *serv)
@@ -110,6 +131,7 @@ svc_destroy(struct svc_serv *serv)
110 131
111 /* Unregister service with the portmapper */ 132 /* Unregister service with the portmapper */
112 svc_register(serv, 0, 0); 133 svc_register(serv, 0, 0);
134 kfree(serv->sv_pools);
113 kfree(serv); 135 kfree(serv);
114} 136}
115 137
@@ -158,10 +180,11 @@ svc_release_buffer(struct svc_rqst *rqstp)
158} 180}
159 181
160/* 182/*
161 * Create a server thread 183 * Create a thread in the given pool. Caller must hold BKL.
162 */ 184 */
163int 185static int
164svc_create_thread(svc_thread_fn func, struct svc_serv *serv) 186__svc_create_thread(svc_thread_fn func, struct svc_serv *serv,
187 struct svc_pool *pool)
165{ 188{
166 struct svc_rqst *rqstp; 189 struct svc_rqst *rqstp;
167 int error = -ENOMEM; 190 int error = -ENOMEM;
@@ -178,7 +201,11 @@ svc_create_thread(svc_thread_fn func, struct svc_serv *serv)
178 goto out_thread; 201 goto out_thread;
179 202
180 serv->sv_nrthreads++; 203 serv->sv_nrthreads++;
204 spin_lock_bh(&pool->sp_lock);
205 pool->sp_nrthreads++;
206 spin_unlock_bh(&pool->sp_lock);
181 rqstp->rq_server = serv; 207 rqstp->rq_server = serv;
208 rqstp->rq_pool = pool;
182 error = kernel_thread((int (*)(void *)) func, rqstp, 0); 209 error = kernel_thread((int (*)(void *)) func, rqstp, 0);
183 if (error < 0) 210 if (error < 0)
184 goto out_thread; 211 goto out_thread;
@@ -193,17 +220,32 @@ out_thread:
193} 220}
194 221
195/* 222/*
196 * Destroy an RPC server thread 223 * Create a thread in the default pool. Caller must hold BKL.
224 */
225int
226svc_create_thread(svc_thread_fn func, struct svc_serv *serv)
227{
228 return __svc_create_thread(func, serv, &serv->sv_pools[0]);
229}
230
231/*
232 * Called from a server thread as it's exiting. Caller must hold BKL.
197 */ 233 */
198void 234void
199svc_exit_thread(struct svc_rqst *rqstp) 235svc_exit_thread(struct svc_rqst *rqstp)
200{ 236{
201 struct svc_serv *serv = rqstp->rq_server; 237 struct svc_serv *serv = rqstp->rq_server;
238 struct svc_pool *pool = rqstp->rq_pool;
202 239
203 svc_release_buffer(rqstp); 240 svc_release_buffer(rqstp);
204 kfree(rqstp->rq_resp); 241 kfree(rqstp->rq_resp);
205 kfree(rqstp->rq_argp); 242 kfree(rqstp->rq_argp);
206 kfree(rqstp->rq_auth_data); 243 kfree(rqstp->rq_auth_data);
244
245 spin_lock_bh(&pool->sp_lock);
246 pool->sp_nrthreads--;
247 spin_unlock_bh(&pool->sp_lock);
248
207 kfree(rqstp); 249 kfree(rqstp);
208 250
209 /* Release the server */ 251 /* Release the server */