diff options
Diffstat (limited to 'net/sunrpc/svc.c')
-rw-r--r-- | net/sunrpc/svc.c | 56 |
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 | */ |
74 | void | 95 | void |
75 | svc_destroy(struct svc_serv *serv) | 96 | svc_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 | */ |
163 | int | 185 | static int |
164 | svc_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 | */ | ||
225 | int | ||
226 | svc_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 | */ |
198 | void | 234 | void |
199 | svc_exit_thread(struct svc_rqst *rqstp) | 235 | svc_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 */ |