aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/sunrpc/svc.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/sunrpc/svc.h')
-rw-r--r--include/linux/sunrpc/svc.h213
1 files changed, 129 insertions, 84 deletions
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 7b27c09b5604..d6288e89fd9d 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -13,11 +13,36 @@
13#include <linux/in.h> 13#include <linux/in.h>
14#include <linux/sunrpc/types.h> 14#include <linux/sunrpc/types.h>
15#include <linux/sunrpc/xdr.h> 15#include <linux/sunrpc/xdr.h>
16#include <linux/sunrpc/auth.h>
16#include <linux/sunrpc/svcauth.h> 17#include <linux/sunrpc/svcauth.h>
17#include <linux/wait.h> 18#include <linux/wait.h>
18#include <linux/mm.h> 19#include <linux/mm.h>
19 20
20/* 21/*
22 * This is the RPC server thread function prototype
23 */
24typedef void (*svc_thread_fn)(struct svc_rqst *);
25
26/*
27 *
28 * RPC service thread pool.
29 *
30 * Pool of threads and temporary sockets. Generally there is only
31 * a single one of these per RPC service, but on NUMA machines those
32 * services that can benefit from it (i.e. nfs but not lockd) will
33 * have one pool per NUMA node. This optimisation reduces cross-
34 * node traffic on multi-node NUMA NFS servers.
35 */
36struct svc_pool {
37 unsigned int sp_id; /* pool id; also node id on NUMA */
38 spinlock_t sp_lock; /* protects all fields */
39 struct list_head sp_threads; /* idle server threads */
40 struct list_head sp_sockets; /* pending sockets */
41 unsigned int sp_nrthreads; /* # of threads in pool */
42 struct list_head sp_all_threads; /* all server threads */
43} ____cacheline_aligned_in_smp;
44
45/*
21 * RPC service. 46 * RPC service.
22 * 47 *
23 * An RPC service is a ``daemon,'' possibly multithreaded, which 48 * An RPC service is a ``daemon,'' possibly multithreaded, which
@@ -28,8 +53,6 @@
28 * We currently do not support more than one RPC program per daemon. 53 * We currently do not support more than one RPC program per daemon.
29 */ 54 */
30struct svc_serv { 55struct svc_serv {
31 struct list_head sv_threads; /* idle server threads */
32 struct list_head sv_sockets; /* pending sockets */
33 struct svc_program * sv_program; /* RPC program */ 56 struct svc_program * sv_program; /* RPC program */
34 struct svc_stat * sv_stats; /* RPC statistics */ 57 struct svc_stat * sv_stats; /* RPC statistics */
35 spinlock_t sv_lock; 58 spinlock_t sv_lock;
@@ -40,16 +63,61 @@ struct svc_serv {
40 struct list_head sv_permsocks; /* all permanent sockets */ 63 struct list_head sv_permsocks; /* all permanent sockets */
41 struct list_head sv_tempsocks; /* all temporary sockets */ 64 struct list_head sv_tempsocks; /* all temporary sockets */
42 int sv_tmpcnt; /* count of temporary sockets */ 65 int sv_tmpcnt; /* count of temporary sockets */
66 struct timer_list sv_temptimer; /* timer for aging temporary sockets */
43 67
44 char * sv_name; /* service name */ 68 char * sv_name; /* service name */
69
70 unsigned int sv_nrpools; /* number of thread pools */
71 struct svc_pool * sv_pools; /* array of thread pools */
72
73 void (*sv_shutdown)(struct svc_serv *serv);
74 /* Callback to use when last thread
75 * exits.
76 */
77
78 struct module * sv_module; /* optional module to count when
79 * adding threads */
80 svc_thread_fn sv_function; /* main function for threads */
81 int sv_kill_signal; /* signal to kill threads */
45}; 82};
46 83
47/* 84/*
85 * We use sv_nrthreads as a reference count. svc_destroy() drops
86 * this refcount, so we need to bump it up around operations that
87 * change the number of threads. Horrible, but there it is.
88 * Should be called with the BKL held.
89 */
90static inline void svc_get(struct svc_serv *serv)
91{
92 serv->sv_nrthreads++;
93}
94
95/*
48 * Maximum payload size supported by a kernel RPC server. 96 * Maximum payload size supported by a kernel RPC server.
49 * This is use to determine the max number of pages nfsd is 97 * This is use to determine the max number of pages nfsd is
50 * willing to return in a single READ operation. 98 * willing to return in a single READ operation.
99 *
100 * These happen to all be powers of 2, which is not strictly
101 * necessary but helps enforce the real limitation, which is
102 * that they should be multiples of PAGE_CACHE_SIZE.
103 *
104 * For UDP transports, a block plus NFS,RPC, and UDP headers
105 * has to fit into the IP datagram limit of 64K. The largest
106 * feasible number for all known page sizes is probably 48K,
107 * but we choose 32K here. This is the same as the historical
108 * Linux limit; someone who cares more about NFS/UDP performance
109 * can test a larger number.
110 *
111 * For TCP transports we have more freedom. A size of 1MB is
112 * chosen to match the client limit. Other OSes are known to
113 * have larger limits, but those numbers are probably beyond
114 * the point of diminishing returns.
51 */ 115 */
52#define RPCSVC_MAXPAYLOAD (64*1024u) 116#define RPCSVC_MAXPAYLOAD (1*1024*1024u)
117#define RPCSVC_MAXPAYLOAD_TCP RPCSVC_MAXPAYLOAD
118#define RPCSVC_MAXPAYLOAD_UDP (32*1024u)
119
120extern u32 svc_max_payload(const struct svc_rqst *rqstp);
53 121
54/* 122/*
55 * RPC Requsts and replies are stored in one or more pages. 123 * RPC Requsts and replies are stored in one or more pages.
@@ -78,43 +146,61 @@ struct svc_serv {
78 */ 146 */
79#define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE + 2) 147#define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE + 2)
80 148
81static inline u32 svc_getu32(struct kvec *iov) 149static inline u32 svc_getnl(struct kvec *iov)
150{
151 __be32 val, *vp;
152 vp = iov->iov_base;
153 val = *vp++;
154 iov->iov_base = (void*)vp;
155 iov->iov_len -= sizeof(__be32);
156 return ntohl(val);
157}
158
159static inline void svc_putnl(struct kvec *iov, u32 val)
160{
161 __be32 *vp = iov->iov_base + iov->iov_len;
162 *vp = htonl(val);
163 iov->iov_len += sizeof(__be32);
164}
165
166static inline __be32 svc_getu32(struct kvec *iov)
82{ 167{
83 u32 val, *vp; 168 __be32 val, *vp;
84 vp = iov->iov_base; 169 vp = iov->iov_base;
85 val = *vp++; 170 val = *vp++;
86 iov->iov_base = (void*)vp; 171 iov->iov_base = (void*)vp;
87 iov->iov_len -= sizeof(u32); 172 iov->iov_len -= sizeof(__be32);
88 return val; 173 return val;
89} 174}
90 175
91static inline void svc_ungetu32(struct kvec *iov) 176static inline void svc_ungetu32(struct kvec *iov)
92{ 177{
93 u32 *vp = (u32 *)iov->iov_base; 178 __be32 *vp = (__be32 *)iov->iov_base;
94 iov->iov_base = (void *)(vp - 1); 179 iov->iov_base = (void *)(vp - 1);
95 iov->iov_len += sizeof(*vp); 180 iov->iov_len += sizeof(*vp);
96} 181}
97 182
98static inline void svc_putu32(struct kvec *iov, u32 val) 183static inline void svc_putu32(struct kvec *iov, __be32 val)
99{ 184{
100 u32 *vp = iov->iov_base + iov->iov_len; 185 __be32 *vp = iov->iov_base + iov->iov_len;
101 *vp = val; 186 *vp = val;
102 iov->iov_len += sizeof(u32); 187 iov->iov_len += sizeof(__be32);
103} 188}
104 189
105 190
106/* 191/*
107 * The context of a single thread, including the request currently being 192 * The context of a single thread, including the request currently being
108 * processed. 193 * processed.
109 * NOTE: First two items must be prev/next.
110 */ 194 */
111struct svc_rqst { 195struct svc_rqst {
112 struct list_head rq_list; /* idle list */ 196 struct list_head rq_list; /* idle list */
197 struct list_head rq_all; /* all threads list */
113 struct svc_sock * rq_sock; /* socket */ 198 struct svc_sock * rq_sock; /* socket */
114 struct sockaddr_in rq_addr; /* peer address */ 199 struct sockaddr_in rq_addr; /* peer address */
115 int rq_addrlen; 200 int rq_addrlen;
116 201
117 struct svc_serv * rq_server; /* RPC service definition */ 202 struct svc_serv * rq_server; /* RPC service definition */
203 struct svc_pool * rq_pool; /* thread pool */
118 struct svc_procedure * rq_procinfo; /* procedure info */ 204 struct svc_procedure * rq_procinfo; /* procedure info */
119 struct auth_ops * rq_authop; /* authentication flavour */ 205 struct auth_ops * rq_authop; /* authentication flavour */
120 struct svc_cred rq_cred; /* auth info */ 206 struct svc_cred rq_cred; /* auth info */
@@ -123,14 +209,13 @@ struct svc_rqst {
123 209
124 struct xdr_buf rq_arg; 210 struct xdr_buf rq_arg;
125 struct xdr_buf rq_res; 211 struct xdr_buf rq_res;
126 struct page * rq_argpages[RPCSVC_MAXPAGES]; 212 struct page * rq_pages[RPCSVC_MAXPAGES];
127 struct page * rq_respages[RPCSVC_MAXPAGES]; 213 struct page * *rq_respages; /* points into rq_pages */
128 int rq_restailpage; 214 int rq_resused; /* number of pages used for result */
129 short rq_argused; /* pages used for argument */ 215
130 short rq_arghi; /* pages available in argument page list */ 216 struct kvec rq_vec[RPCSVC_MAXPAGES]; /* generally useful.. */
131 short rq_resused; /* pages used for result */ 217
132 218 __be32 rq_xid; /* transmission id */
133 u32 rq_xid; /* transmission id */
134 u32 rq_prog; /* program number */ 219 u32 rq_prog; /* program number */
135 u32 rq_vers; /* program version */ 220 u32 rq_vers; /* program version */
136 u32 rq_proc; /* procedure number */ 221 u32 rq_proc; /* procedure number */
@@ -139,7 +224,7 @@ struct svc_rqst {
139 rq_secure : 1; /* secure port */ 224 rq_secure : 1; /* secure port */
140 225
141 226
142 __u32 rq_daddr; /* dest addr of request - reply from here */ 227 __be32 rq_daddr; /* dest addr of request - reply from here */
143 228
144 void * rq_argp; /* decoded arguments */ 229 void * rq_argp; /* decoded arguments */
145 void * rq_resp; /* xdr'd results */ 230 void * rq_resp; /* xdr'd results */
@@ -163,13 +248,14 @@ struct svc_rqst {
163 * to prevent encrypting page 248 * to prevent encrypting page
164 * cache pages */ 249 * cache pages */
165 wait_queue_head_t rq_wait; /* synchronization */ 250 wait_queue_head_t rq_wait; /* synchronization */
251 struct task_struct *rq_task; /* service thread */
166}; 252};
167 253
168/* 254/*
169 * Check buffer bounds after decoding arguments 255 * Check buffer bounds after decoding arguments
170 */ 256 */
171static inline int 257static inline int
172xdr_argsize_check(struct svc_rqst *rqstp, u32 *p) 258xdr_argsize_check(struct svc_rqst *rqstp, __be32 *p)
173{ 259{
174 char *cp = (char *)p; 260 char *cp = (char *)p;
175 struct kvec *vec = &rqstp->rq_arg.head[0]; 261 struct kvec *vec = &rqstp->rq_arg.head[0];
@@ -178,7 +264,7 @@ xdr_argsize_check(struct svc_rqst *rqstp, u32 *p)
178} 264}
179 265
180static inline int 266static inline int
181xdr_ressize_check(struct svc_rqst *rqstp, u32 *p) 267xdr_ressize_check(struct svc_rqst *rqstp, __be32 *p)
182{ 268{
183 struct kvec *vec = &rqstp->rq_res.head[0]; 269 struct kvec *vec = &rqstp->rq_res.head[0];
184 char *cp = (char*)p; 270 char *cp = (char*)p;
@@ -188,71 +274,26 @@ xdr_ressize_check(struct svc_rqst *rqstp, u32 *p)
188 return vec->iov_len <= PAGE_SIZE; 274 return vec->iov_len <= PAGE_SIZE;
189} 275}
190 276
191static inline struct page * 277static inline void svc_free_res_pages(struct svc_rqst *rqstp)
192svc_take_res_page(struct svc_rqst *rqstp)
193{
194 if (rqstp->rq_arghi <= rqstp->rq_argused)
195 return NULL;
196 rqstp->rq_arghi--;
197 rqstp->rq_respages[rqstp->rq_resused] =
198 rqstp->rq_argpages[rqstp->rq_arghi];
199 return rqstp->rq_respages[rqstp->rq_resused++];
200}
201
202static inline void svc_take_page(struct svc_rqst *rqstp)
203{
204 if (rqstp->rq_arghi <= rqstp->rq_argused) {
205 WARN_ON(1);
206 return;
207 }
208 rqstp->rq_arghi--;
209 rqstp->rq_respages[rqstp->rq_resused] =
210 rqstp->rq_argpages[rqstp->rq_arghi];
211 rqstp->rq_resused++;
212}
213
214static inline void svc_pushback_allpages(struct svc_rqst *rqstp)
215{
216 while (rqstp->rq_resused) {
217 if (rqstp->rq_respages[--rqstp->rq_resused] == NULL)
218 continue;
219 rqstp->rq_argpages[rqstp->rq_arghi++] =
220 rqstp->rq_respages[rqstp->rq_resused];
221 rqstp->rq_respages[rqstp->rq_resused] = NULL;
222 }
223}
224
225static inline void svc_pushback_unused_pages(struct svc_rqst *rqstp)
226{ 278{
227 while (rqstp->rq_resused && 279 while (rqstp->rq_resused) {
228 rqstp->rq_res.pages != &rqstp->rq_respages[rqstp->rq_resused]) { 280 struct page **pp = (rqstp->rq_respages +
229 281 --rqstp->rq_resused);
230 if (rqstp->rq_respages[--rqstp->rq_resused] != NULL) { 282 if (*pp) {
231 rqstp->rq_argpages[rqstp->rq_arghi++] = 283 put_page(*pp);
232 rqstp->rq_respages[rqstp->rq_resused]; 284 *pp = NULL;
233 rqstp->rq_respages[rqstp->rq_resused] = NULL;
234 } 285 }
235 } 286 }
236} 287}
237 288
238static inline void svc_free_allpages(struct svc_rqst *rqstp)
239{
240 while (rqstp->rq_resused) {
241 if (rqstp->rq_respages[--rqstp->rq_resused] == NULL)
242 continue;
243 put_page(rqstp->rq_respages[rqstp->rq_resused]);
244 rqstp->rq_respages[rqstp->rq_resused] = NULL;
245 }
246}
247
248struct svc_deferred_req { 289struct svc_deferred_req {
249 u32 prot; /* protocol (UDP or TCP) */ 290 u32 prot; /* protocol (UDP or TCP) */
250 struct sockaddr_in addr; 291 struct sockaddr_in addr;
251 struct svc_sock *svsk; /* where reply must go */ 292 struct svc_sock *svsk; /* where reply must go */
252 u32 daddr; /* where reply must come from */ 293 __be32 daddr; /* where reply must come from */
253 struct cache_deferred_req handle; 294 struct cache_deferred_req handle;
254 int argslen; 295 int argslen;
255 u32 args[0]; 296 __be32 args[0];
256}; 297};
257 298
258/* 299/*
@@ -280,11 +321,14 @@ struct svc_version {
280 struct svc_procedure * vs_proc; /* per-procedure info */ 321 struct svc_procedure * vs_proc; /* per-procedure info */
281 u32 vs_xdrsize; /* xdrsize needed for this version */ 322 u32 vs_xdrsize; /* xdrsize needed for this version */
282 323
324 unsigned int vs_hidden : 1; /* Don't register with portmapper.
325 * Only used for nfsacl so far. */
326
283 /* Override dispatch function (e.g. when caching replies). 327 /* Override dispatch function (e.g. when caching replies).
284 * A return value of 0 means drop the request. 328 * A return value of 0 means drop the request.
285 * vs_dispatch == NULL means use default dispatcher. 329 * vs_dispatch == NULL means use default dispatcher.
286 */ 330 */
287 int (*vs_dispatch)(struct svc_rqst *, u32 *); 331 int (*vs_dispatch)(struct svc_rqst *, __be32 *);
288}; 332};
289 333
290/* 334/*
@@ -304,20 +348,21 @@ struct svc_procedure {
304}; 348};
305 349
306/* 350/*
307 * This is the RPC server thread function prototype
308 */
309typedef void (*svc_thread_fn)(struct svc_rqst *);
310
311/*
312 * Function prototypes. 351 * Function prototypes.
313 */ 352 */
314struct svc_serv * svc_create(struct svc_program *, unsigned int); 353struct svc_serv * svc_create(struct svc_program *, unsigned int,
354 void (*shutdown)(struct svc_serv*));
315int svc_create_thread(svc_thread_fn, struct svc_serv *); 355int svc_create_thread(svc_thread_fn, struct svc_serv *);
316void svc_exit_thread(struct svc_rqst *); 356void svc_exit_thread(struct svc_rqst *);
357struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int,
358 void (*shutdown)(struct svc_serv*),
359 svc_thread_fn, int sig, struct module *);
360int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
317void svc_destroy(struct svc_serv *); 361void svc_destroy(struct svc_serv *);
318int svc_process(struct svc_serv *, struct svc_rqst *); 362int svc_process(struct svc_rqst *);
319int svc_register(struct svc_serv *, int, unsigned short); 363int svc_register(struct svc_serv *, int, unsigned short);
320void svc_wake_up(struct svc_serv *); 364void svc_wake_up(struct svc_serv *);
321void svc_reserve(struct svc_rqst *rqstp, int space); 365void svc_reserve(struct svc_rqst *rqstp, int space);
366struct svc_pool * svc_pool_for_cpu(struct svc_serv *serv, int cpu);
322 367
323#endif /* SUNRPC_SVC_H */ 368#endif /* SUNRPC_SVC_H */