xref: /freebsd/sys/rpc/svc.c (revision 49b49cda41feabe3439f7318e8bf40e3896c7bf4)
1 /*	$NetBSD: svc.c,v 1.21 2000/07/06 03:10:35 christos Exp $	*/
2 
3 /*-
4  * Copyright (c) 2009, Sun Microsystems, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  * - Redistributions of source code must retain the above copyright notice,
10  *   this list of conditions and the following disclaimer.
11  * - Redistributions in binary form must reproduce the above copyright notice,
12  *   this list of conditions and the following disclaimer in the documentation
13  *   and/or other materials provided with the distribution.
14  * - Neither the name of Sun Microsystems, Inc. nor the names of its
15  *   contributors may be used to endorse or promote products derived
16  *   from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #if defined(LIBC_SCCS) && !defined(lint)
32 static char *sccsid2 = "@(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro";
33 static char *sccsid = "@(#)svc.c	2.4 88/08/11 4.0 RPCSRC";
34 #endif
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37 
38 /*
39  * svc.c, Server-side remote procedure call interface.
40  *
41  * There are two sets of procedures here.  The xprt routines are
42  * for handling transport handles.  The svc routines handle the
43  * list of service routines.
44  *
45  * Copyright (C) 1984, Sun Microsystems, Inc.
46  */
47 
48 #include <sys/param.h>
49 #include <sys/lock.h>
50 #include <sys/kernel.h>
51 #include <sys/kthread.h>
52 #include <sys/malloc.h>
53 #include <sys/mbuf.h>
54 #include <sys/mutex.h>
55 #include <sys/proc.h>
56 #include <sys/queue.h>
57 #include <sys/socketvar.h>
58 #include <sys/systm.h>
59 #include <sys/smp.h>
60 #include <sys/sx.h>
61 #include <sys/ucred.h>
62 
63 #include <rpc/rpc.h>
64 #include <rpc/rpcb_clnt.h>
65 #include <rpc/replay.h>
66 
67 #include <rpc/rpc_com.h>
68 
69 #define SVC_VERSQUIET 0x0001		/* keep quiet about vers mismatch */
70 #define version_keepquiet(xp) (SVC_EXT(xp)->xp_flags & SVC_VERSQUIET)
71 
72 static struct svc_callout *svc_find(SVCPOOL *pool, rpcprog_t, rpcvers_t,
73     char *);
74 static void svc_new_thread(SVCGROUP *grp);
75 static void xprt_unregister_locked(SVCXPRT *xprt);
76 static void svc_change_space_used(SVCPOOL *pool, long delta);
77 static bool_t svc_request_space_available(SVCPOOL *pool);
78 
79 /* ***************  SVCXPRT related stuff **************** */
80 
81 static int svcpool_minthread_sysctl(SYSCTL_HANDLER_ARGS);
82 static int svcpool_maxthread_sysctl(SYSCTL_HANDLER_ARGS);
83 static int svcpool_threads_sysctl(SYSCTL_HANDLER_ARGS);
84 
85 SVCPOOL*
86 svcpool_create(const char *name, struct sysctl_oid_list *sysctl_base)
87 {
88 	SVCPOOL *pool;
89 	SVCGROUP *grp;
90 	int g;
91 
92 	pool = malloc(sizeof(SVCPOOL), M_RPC, M_WAITOK|M_ZERO);
93 
94 	mtx_init(&pool->sp_lock, "sp_lock", NULL, MTX_DEF);
95 	pool->sp_name = name;
96 	pool->sp_state = SVCPOOL_INIT;
97 	pool->sp_proc = NULL;
98 	TAILQ_INIT(&pool->sp_callouts);
99 	TAILQ_INIT(&pool->sp_lcallouts);
100 	pool->sp_minthreads = 1;
101 	pool->sp_maxthreads = 1;
102 	pool->sp_groupcount = 1;
103 	for (g = 0; g < SVC_MAXGROUPS; g++) {
104 		grp = &pool->sp_groups[g];
105 		mtx_init(&grp->sg_lock, "sg_lock", NULL, MTX_DEF);
106 		grp->sg_pool = pool;
107 		grp->sg_state = SVCPOOL_ACTIVE;
108 		TAILQ_INIT(&grp->sg_xlist);
109 		TAILQ_INIT(&grp->sg_active);
110 		LIST_INIT(&grp->sg_idlethreads);
111 		grp->sg_minthreads = 1;
112 		grp->sg_maxthreads = 1;
113 	}
114 
115 	/*
116 	 * Don't use more than a quarter of mbuf clusters.  Nota bene:
117 	 * nmbclusters is an int, but nmbclusters*MCLBYTES may overflow
118 	 * on LP64 architectures, so cast to u_long to avoid undefined
119 	 * behavior.  (ILP32 architectures cannot have nmbclusters
120 	 * large enough to overflow for other reasons.)
121 	 */
122 	pool->sp_space_high = (u_long)nmbclusters * MCLBYTES / 4;
123 	pool->sp_space_low = (pool->sp_space_high / 3) * 2;
124 
125 	sysctl_ctx_init(&pool->sp_sysctl);
126 	if (sysctl_base) {
127 		SYSCTL_ADD_PROC(&pool->sp_sysctl, sysctl_base, OID_AUTO,
128 		    "minthreads", CTLTYPE_INT | CTLFLAG_RW,
129 		    pool, 0, svcpool_minthread_sysctl, "I",
130 		    "Minimal number of threads");
131 		SYSCTL_ADD_PROC(&pool->sp_sysctl, sysctl_base, OID_AUTO,
132 		    "maxthreads", CTLTYPE_INT | CTLFLAG_RW,
133 		    pool, 0, svcpool_maxthread_sysctl, "I",
134 		    "Maximal number of threads");
135 		SYSCTL_ADD_PROC(&pool->sp_sysctl, sysctl_base, OID_AUTO,
136 		    "threads", CTLTYPE_INT | CTLFLAG_RD,
137 		    pool, 0, svcpool_threads_sysctl, "I",
138 		    "Current number of threads");
139 		SYSCTL_ADD_INT(&pool->sp_sysctl, sysctl_base, OID_AUTO,
140 		    "groups", CTLFLAG_RD, &pool->sp_groupcount, 0,
141 		    "Number of thread groups");
142 
143 		SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO,
144 		    "request_space_used", CTLFLAG_RD,
145 		    &pool->sp_space_used,
146 		    "Space in parsed but not handled requests.");
147 
148 		SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO,
149 		    "request_space_used_highest", CTLFLAG_RD,
150 		    &pool->sp_space_used_highest,
151 		    "Highest space used since reboot.");
152 
153 		SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO,
154 		    "request_space_high", CTLFLAG_RW,
155 		    &pool->sp_space_high,
156 		    "Maximum space in parsed but not handled requests.");
157 
158 		SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO,
159 		    "request_space_low", CTLFLAG_RW,
160 		    &pool->sp_space_low,
161 		    "Low water mark for request space.");
162 
163 		SYSCTL_ADD_INT(&pool->sp_sysctl, sysctl_base, OID_AUTO,
164 		    "request_space_throttled", CTLFLAG_RD,
165 		    &pool->sp_space_throttled, 0,
166 		    "Whether nfs requests are currently throttled");
167 
168 		SYSCTL_ADD_INT(&pool->sp_sysctl, sysctl_base, OID_AUTO,
169 		    "request_space_throttle_count", CTLFLAG_RD,
170 		    &pool->sp_space_throttle_count, 0,
171 		    "Count of times throttling based on request space has occurred");
172 	}
173 
174 	return pool;
175 }
176 
177 void
178 svcpool_destroy(SVCPOOL *pool)
179 {
180 	SVCGROUP *grp;
181 	SVCXPRT *xprt, *nxprt;
182 	struct svc_callout *s;
183 	struct svc_loss_callout *sl;
184 	struct svcxprt_list cleanup;
185 	int g;
186 
187 	TAILQ_INIT(&cleanup);
188 
189 	for (g = 0; g < SVC_MAXGROUPS; g++) {
190 		grp = &pool->sp_groups[g];
191 		mtx_lock(&grp->sg_lock);
192 		while ((xprt = TAILQ_FIRST(&grp->sg_xlist)) != NULL) {
193 			xprt_unregister_locked(xprt);
194 			TAILQ_INSERT_TAIL(&cleanup, xprt, xp_link);
195 		}
196 		mtx_unlock(&grp->sg_lock);
197 	}
198 	TAILQ_FOREACH_SAFE(xprt, &cleanup, xp_link, nxprt) {
199 		SVC_RELEASE(xprt);
200 	}
201 
202 	mtx_lock(&pool->sp_lock);
203 	while ((s = TAILQ_FIRST(&pool->sp_callouts)) != NULL) {
204 		mtx_unlock(&pool->sp_lock);
205 		svc_unreg(pool, s->sc_prog, s->sc_vers);
206 		mtx_lock(&pool->sp_lock);
207 	}
208 	while ((sl = TAILQ_FIRST(&pool->sp_lcallouts)) != NULL) {
209 		mtx_unlock(&pool->sp_lock);
210 		svc_loss_unreg(pool, sl->slc_dispatch);
211 		mtx_lock(&pool->sp_lock);
212 	}
213 	mtx_unlock(&pool->sp_lock);
214 
215 	for (g = 0; g < SVC_MAXGROUPS; g++) {
216 		grp = &pool->sp_groups[g];
217 		mtx_destroy(&grp->sg_lock);
218 	}
219 	mtx_destroy(&pool->sp_lock);
220 
221 	if (pool->sp_rcache)
222 		replay_freecache(pool->sp_rcache);
223 
224 	sysctl_ctx_free(&pool->sp_sysctl);
225 	free(pool, M_RPC);
226 }
227 
228 /*
229  * Sysctl handler to get the present thread count on a pool
230  */
231 static int
232 svcpool_threads_sysctl(SYSCTL_HANDLER_ARGS)
233 {
234 	SVCPOOL *pool;
235 	int threads, error, g;
236 
237 	pool = oidp->oid_arg1;
238 	threads = 0;
239 	mtx_lock(&pool->sp_lock);
240 	for (g = 0; g < pool->sp_groupcount; g++)
241 		threads += pool->sp_groups[g].sg_threadcount;
242 	mtx_unlock(&pool->sp_lock);
243 	error = sysctl_handle_int(oidp, &threads, 0, req);
244 	return (error);
245 }
246 
247 /*
248  * Sysctl handler to set the minimum thread count on a pool
249  */
250 static int
251 svcpool_minthread_sysctl(SYSCTL_HANDLER_ARGS)
252 {
253 	SVCPOOL *pool;
254 	int newminthreads, error, g;
255 
256 	pool = oidp->oid_arg1;
257 	newminthreads = pool->sp_minthreads;
258 	error = sysctl_handle_int(oidp, &newminthreads, 0, req);
259 	if (error == 0 && newminthreads != pool->sp_minthreads) {
260 		if (newminthreads > pool->sp_maxthreads)
261 			return (EINVAL);
262 		mtx_lock(&pool->sp_lock);
263 		pool->sp_minthreads = newminthreads;
264 		for (g = 0; g < pool->sp_groupcount; g++) {
265 			pool->sp_groups[g].sg_minthreads = max(1,
266 			    pool->sp_minthreads / pool->sp_groupcount);
267 		}
268 		mtx_unlock(&pool->sp_lock);
269 	}
270 	return (error);
271 }
272 
273 /*
274  * Sysctl handler to set the maximum thread count on a pool
275  */
276 static int
277 svcpool_maxthread_sysctl(SYSCTL_HANDLER_ARGS)
278 {
279 	SVCPOOL *pool;
280 	int newmaxthreads, error, g;
281 
282 	pool = oidp->oid_arg1;
283 	newmaxthreads = pool->sp_maxthreads;
284 	error = sysctl_handle_int(oidp, &newmaxthreads, 0, req);
285 	if (error == 0 && newmaxthreads != pool->sp_maxthreads) {
286 		if (newmaxthreads < pool->sp_minthreads)
287 			return (EINVAL);
288 		mtx_lock(&pool->sp_lock);
289 		pool->sp_maxthreads = newmaxthreads;
290 		for (g = 0; g < pool->sp_groupcount; g++) {
291 			pool->sp_groups[g].sg_maxthreads = max(1,
292 			    pool->sp_maxthreads / pool->sp_groupcount);
293 		}
294 		mtx_unlock(&pool->sp_lock);
295 	}
296 	return (error);
297 }
298 
299 /*
300  * Activate a transport handle.
301  */
302 void
303 xprt_register(SVCXPRT *xprt)
304 {
305 	SVCPOOL *pool = xprt->xp_pool;
306 	SVCGROUP *grp;
307 	int g;
308 
309 	SVC_ACQUIRE(xprt);
310 	g = atomic_fetchadd_int(&pool->sp_nextgroup, 1) % pool->sp_groupcount;
311 	xprt->xp_group = grp = &pool->sp_groups[g];
312 	mtx_lock(&grp->sg_lock);
313 	xprt->xp_registered = TRUE;
314 	xprt->xp_active = FALSE;
315 	TAILQ_INSERT_TAIL(&grp->sg_xlist, xprt, xp_link);
316 	mtx_unlock(&grp->sg_lock);
317 }
318 
319 /*
320  * De-activate a transport handle. Note: the locked version doesn't
321  * release the transport - caller must do that after dropping the pool
322  * lock.
323  */
324 static void
325 xprt_unregister_locked(SVCXPRT *xprt)
326 {
327 	SVCGROUP *grp = xprt->xp_group;
328 
329 	mtx_assert(&grp->sg_lock, MA_OWNED);
330 	KASSERT(xprt->xp_registered == TRUE,
331 	    ("xprt_unregister_locked: not registered"));
332 	xprt_inactive_locked(xprt);
333 	TAILQ_REMOVE(&grp->sg_xlist, xprt, xp_link);
334 	xprt->xp_registered = FALSE;
335 }
336 
337 void
338 xprt_unregister(SVCXPRT *xprt)
339 {
340 	SVCGROUP *grp = xprt->xp_group;
341 
342 	mtx_lock(&grp->sg_lock);
343 	if (xprt->xp_registered == FALSE) {
344 		/* Already unregistered by another thread */
345 		mtx_unlock(&grp->sg_lock);
346 		return;
347 	}
348 	xprt_unregister_locked(xprt);
349 	mtx_unlock(&grp->sg_lock);
350 
351 	SVC_RELEASE(xprt);
352 }
353 
354 /*
355  * Attempt to assign a service thread to this transport.
356  */
357 static int
358 xprt_assignthread(SVCXPRT *xprt)
359 {
360 	SVCGROUP *grp = xprt->xp_group;
361 	SVCTHREAD *st;
362 
363 	mtx_assert(&grp->sg_lock, MA_OWNED);
364 	st = LIST_FIRST(&grp->sg_idlethreads);
365 	if (st) {
366 		LIST_REMOVE(st, st_ilink);
367 		SVC_ACQUIRE(xprt);
368 		xprt->xp_thread = st;
369 		st->st_xprt = xprt;
370 		cv_signal(&st->st_cond);
371 		return (TRUE);
372 	} else {
373 		/*
374 		 * See if we can create a new thread. The
375 		 * actual thread creation happens in
376 		 * svc_run_internal because our locking state
377 		 * is poorly defined (we are typically called
378 		 * from a socket upcall). Don't create more
379 		 * than one thread per second.
380 		 */
381 		if (grp->sg_state == SVCPOOL_ACTIVE
382 		    && grp->sg_lastcreatetime < time_uptime
383 		    && grp->sg_threadcount < grp->sg_maxthreads) {
384 			grp->sg_state = SVCPOOL_THREADWANTED;
385 		}
386 	}
387 	return (FALSE);
388 }
389 
390 void
391 xprt_active(SVCXPRT *xprt)
392 {
393 	SVCGROUP *grp = xprt->xp_group;
394 
395 	mtx_lock(&grp->sg_lock);
396 
397 	if (!xprt->xp_registered) {
398 		/*
399 		 * Race with xprt_unregister - we lose.
400 		 */
401 		mtx_unlock(&grp->sg_lock);
402 		return;
403 	}
404 
405 	if (!xprt->xp_active) {
406 		xprt->xp_active = TRUE;
407 		if (xprt->xp_thread == NULL) {
408 			if (!svc_request_space_available(xprt->xp_pool) ||
409 			    !xprt_assignthread(xprt))
410 				TAILQ_INSERT_TAIL(&grp->sg_active, xprt,
411 				    xp_alink);
412 		}
413 	}
414 
415 	mtx_unlock(&grp->sg_lock);
416 }
417 
418 void
419 xprt_inactive_locked(SVCXPRT *xprt)
420 {
421 	SVCGROUP *grp = xprt->xp_group;
422 
423 	mtx_assert(&grp->sg_lock, MA_OWNED);
424 	if (xprt->xp_active) {
425 		if (xprt->xp_thread == NULL)
426 			TAILQ_REMOVE(&grp->sg_active, xprt, xp_alink);
427 		xprt->xp_active = FALSE;
428 	}
429 }
430 
431 void
432 xprt_inactive(SVCXPRT *xprt)
433 {
434 	SVCGROUP *grp = xprt->xp_group;
435 
436 	mtx_lock(&grp->sg_lock);
437 	xprt_inactive_locked(xprt);
438 	mtx_unlock(&grp->sg_lock);
439 }
440 
441 /*
442  * Variant of xprt_inactive() for use only when sure that port is
443  * assigned to thread. For example, withing receive handlers.
444  */
445 void
446 xprt_inactive_self(SVCXPRT *xprt)
447 {
448 
449 	KASSERT(xprt->xp_thread != NULL,
450 	    ("xprt_inactive_self(%p) with NULL xp_thread", xprt));
451 	xprt->xp_active = FALSE;
452 }
453 
454 /*
455  * Add a service program to the callout list.
456  * The dispatch routine will be called when a rpc request for this
457  * program number comes in.
458  */
459 bool_t
460 svc_reg(SVCXPRT *xprt, const rpcprog_t prog, const rpcvers_t vers,
461     void (*dispatch)(struct svc_req *, SVCXPRT *),
462     const struct netconfig *nconf)
463 {
464 	SVCPOOL *pool = xprt->xp_pool;
465 	struct svc_callout *s;
466 	char *netid = NULL;
467 	int flag = 0;
468 
469 /* VARIABLES PROTECTED BY svc_lock: s, svc_head */
470 
471 	if (xprt->xp_netid) {
472 		netid = strdup(xprt->xp_netid, M_RPC);
473 		flag = 1;
474 	} else if (nconf && nconf->nc_netid) {
475 		netid = strdup(nconf->nc_netid, M_RPC);
476 		flag = 1;
477 	} /* must have been created with svc_raw_create */
478 	if ((netid == NULL) && (flag == 1)) {
479 		return (FALSE);
480 	}
481 
482 	mtx_lock(&pool->sp_lock);
483 	if ((s = svc_find(pool, prog, vers, netid)) != NULL) {
484 		if (netid)
485 			free(netid, M_RPC);
486 		if (s->sc_dispatch == dispatch)
487 			goto rpcb_it; /* he is registering another xptr */
488 		mtx_unlock(&pool->sp_lock);
489 		return (FALSE);
490 	}
491 	s = malloc(sizeof (struct svc_callout), M_RPC, M_NOWAIT);
492 	if (s == NULL) {
493 		if (netid)
494 			free(netid, M_RPC);
495 		mtx_unlock(&pool->sp_lock);
496 		return (FALSE);
497 	}
498 
499 	s->sc_prog = prog;
500 	s->sc_vers = vers;
501 	s->sc_dispatch = dispatch;
502 	s->sc_netid = netid;
503 	TAILQ_INSERT_TAIL(&pool->sp_callouts, s, sc_link);
504 
505 	if ((xprt->xp_netid == NULL) && (flag == 1) && netid)
506 		((SVCXPRT *) xprt)->xp_netid = strdup(netid, M_RPC);
507 
508 rpcb_it:
509 	mtx_unlock(&pool->sp_lock);
510 	/* now register the information with the local binder service */
511 	if (nconf) {
512 		bool_t dummy;
513 		struct netconfig tnc;
514 		struct netbuf nb;
515 		tnc = *nconf;
516 		nb.buf = &xprt->xp_ltaddr;
517 		nb.len = xprt->xp_ltaddr.ss_len;
518 		dummy = rpcb_set(prog, vers, &tnc, &nb);
519 		return (dummy);
520 	}
521 	return (TRUE);
522 }
523 
524 /*
525  * Remove a service program from the callout list.
526  */
527 void
528 svc_unreg(SVCPOOL *pool, const rpcprog_t prog, const rpcvers_t vers)
529 {
530 	struct svc_callout *s;
531 
532 	/* unregister the information anyway */
533 	(void) rpcb_unset(prog, vers, NULL);
534 	mtx_lock(&pool->sp_lock);
535 	while ((s = svc_find(pool, prog, vers, NULL)) != NULL) {
536 		TAILQ_REMOVE(&pool->sp_callouts, s, sc_link);
537 		if (s->sc_netid)
538 			mem_free(s->sc_netid, sizeof (s->sc_netid) + 1);
539 		mem_free(s, sizeof (struct svc_callout));
540 	}
541 	mtx_unlock(&pool->sp_lock);
542 }
543 
544 /*
545  * Add a service connection loss program to the callout list.
546  * The dispatch routine will be called when some port in ths pool die.
547  */
548 bool_t
549 svc_loss_reg(SVCXPRT *xprt, void (*dispatch)(SVCXPRT *))
550 {
551 	SVCPOOL *pool = xprt->xp_pool;
552 	struct svc_loss_callout *s;
553 
554 	mtx_lock(&pool->sp_lock);
555 	TAILQ_FOREACH(s, &pool->sp_lcallouts, slc_link) {
556 		if (s->slc_dispatch == dispatch)
557 			break;
558 	}
559 	if (s != NULL) {
560 		mtx_unlock(&pool->sp_lock);
561 		return (TRUE);
562 	}
563 	s = malloc(sizeof (struct svc_callout), M_RPC, M_NOWAIT);
564 	if (s == NULL) {
565 		mtx_unlock(&pool->sp_lock);
566 		return (FALSE);
567 	}
568 	s->slc_dispatch = dispatch;
569 	TAILQ_INSERT_TAIL(&pool->sp_lcallouts, s, slc_link);
570 	mtx_unlock(&pool->sp_lock);
571 	return (TRUE);
572 }
573 
574 /*
575  * Remove a service connection loss program from the callout list.
576  */
577 void
578 svc_loss_unreg(SVCPOOL *pool, void (*dispatch)(SVCXPRT *))
579 {
580 	struct svc_loss_callout *s;
581 
582 	mtx_lock(&pool->sp_lock);
583 	TAILQ_FOREACH(s, &pool->sp_lcallouts, slc_link) {
584 		if (s->slc_dispatch == dispatch) {
585 			TAILQ_REMOVE(&pool->sp_lcallouts, s, slc_link);
586 			free(s, M_RPC);
587 			break;
588 		}
589 	}
590 	mtx_unlock(&pool->sp_lock);
591 }
592 
593 /* ********************** CALLOUT list related stuff ************* */
594 
595 /*
596  * Search the callout list for a program number, return the callout
597  * struct.
598  */
599 static struct svc_callout *
600 svc_find(SVCPOOL *pool, rpcprog_t prog, rpcvers_t vers, char *netid)
601 {
602 	struct svc_callout *s;
603 
604 	mtx_assert(&pool->sp_lock, MA_OWNED);
605 	TAILQ_FOREACH(s, &pool->sp_callouts, sc_link) {
606 		if (s->sc_prog == prog && s->sc_vers == vers
607 		    && (netid == NULL || s->sc_netid == NULL ||
608 			strcmp(netid, s->sc_netid) == 0))
609 			break;
610 	}
611 
612 	return (s);
613 }
614 
615 /* ******************* REPLY GENERATION ROUTINES  ************ */
616 
617 static bool_t
618 svc_sendreply_common(struct svc_req *rqstp, struct rpc_msg *rply,
619     struct mbuf *body)
620 {
621 	SVCXPRT *xprt = rqstp->rq_xprt;
622 	bool_t ok;
623 
624 	if (rqstp->rq_args) {
625 		m_freem(rqstp->rq_args);
626 		rqstp->rq_args = NULL;
627 	}
628 
629 	if (xprt->xp_pool->sp_rcache)
630 		replay_setreply(xprt->xp_pool->sp_rcache,
631 		    rply, svc_getrpccaller(rqstp), body);
632 
633 	if (!SVCAUTH_WRAP(&rqstp->rq_auth, &body))
634 		return (FALSE);
635 
636 	ok = SVC_REPLY(xprt, rply, rqstp->rq_addr, body, &rqstp->rq_reply_seq);
637 	if (rqstp->rq_addr) {
638 		free(rqstp->rq_addr, M_SONAME);
639 		rqstp->rq_addr = NULL;
640 	}
641 
642 	return (ok);
643 }
644 
645 /*
646  * Send a reply to an rpc request
647  */
648 bool_t
649 svc_sendreply(struct svc_req *rqstp, xdrproc_t xdr_results, void * xdr_location)
650 {
651 	struct rpc_msg rply;
652 	struct mbuf *m;
653 	XDR xdrs;
654 	bool_t ok;
655 
656 	rply.rm_xid = rqstp->rq_xid;
657 	rply.rm_direction = REPLY;
658 	rply.rm_reply.rp_stat = MSG_ACCEPTED;
659 	rply.acpted_rply.ar_verf = rqstp->rq_verf;
660 	rply.acpted_rply.ar_stat = SUCCESS;
661 	rply.acpted_rply.ar_results.where = NULL;
662 	rply.acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
663 
664 	m = m_getcl(M_WAITOK, MT_DATA, 0);
665 	xdrmbuf_create(&xdrs, m, XDR_ENCODE);
666 	ok = xdr_results(&xdrs, xdr_location);
667 	XDR_DESTROY(&xdrs);
668 
669 	if (ok) {
670 		return (svc_sendreply_common(rqstp, &rply, m));
671 	} else {
672 		m_freem(m);
673 		return (FALSE);
674 	}
675 }
676 
677 bool_t
678 svc_sendreply_mbuf(struct svc_req *rqstp, struct mbuf *m)
679 {
680 	struct rpc_msg rply;
681 
682 	rply.rm_xid = rqstp->rq_xid;
683 	rply.rm_direction = REPLY;
684 	rply.rm_reply.rp_stat = MSG_ACCEPTED;
685 	rply.acpted_rply.ar_verf = rqstp->rq_verf;
686 	rply.acpted_rply.ar_stat = SUCCESS;
687 	rply.acpted_rply.ar_results.where = NULL;
688 	rply.acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
689 
690 	return (svc_sendreply_common(rqstp, &rply, m));
691 }
692 
693 /*
694  * No procedure error reply
695  */
696 void
697 svcerr_noproc(struct svc_req *rqstp)
698 {
699 	SVCXPRT *xprt = rqstp->rq_xprt;
700 	struct rpc_msg rply;
701 
702 	rply.rm_xid = rqstp->rq_xid;
703 	rply.rm_direction = REPLY;
704 	rply.rm_reply.rp_stat = MSG_ACCEPTED;
705 	rply.acpted_rply.ar_verf = rqstp->rq_verf;
706 	rply.acpted_rply.ar_stat = PROC_UNAVAIL;
707 
708 	if (xprt->xp_pool->sp_rcache)
709 		replay_setreply(xprt->xp_pool->sp_rcache,
710 		    &rply, svc_getrpccaller(rqstp), NULL);
711 
712 	svc_sendreply_common(rqstp, &rply, NULL);
713 }
714 
715 /*
716  * Can't decode args error reply
717  */
718 void
719 svcerr_decode(struct svc_req *rqstp)
720 {
721 	SVCXPRT *xprt = rqstp->rq_xprt;
722 	struct rpc_msg rply;
723 
724 	rply.rm_xid = rqstp->rq_xid;
725 	rply.rm_direction = REPLY;
726 	rply.rm_reply.rp_stat = MSG_ACCEPTED;
727 	rply.acpted_rply.ar_verf = rqstp->rq_verf;
728 	rply.acpted_rply.ar_stat = GARBAGE_ARGS;
729 
730 	if (xprt->xp_pool->sp_rcache)
731 		replay_setreply(xprt->xp_pool->sp_rcache,
732 		    &rply, (struct sockaddr *) &xprt->xp_rtaddr, NULL);
733 
734 	svc_sendreply_common(rqstp, &rply, NULL);
735 }
736 
737 /*
738  * Some system error
739  */
740 void
741 svcerr_systemerr(struct svc_req *rqstp)
742 {
743 	SVCXPRT *xprt = rqstp->rq_xprt;
744 	struct rpc_msg rply;
745 
746 	rply.rm_xid = rqstp->rq_xid;
747 	rply.rm_direction = REPLY;
748 	rply.rm_reply.rp_stat = MSG_ACCEPTED;
749 	rply.acpted_rply.ar_verf = rqstp->rq_verf;
750 	rply.acpted_rply.ar_stat = SYSTEM_ERR;
751 
752 	if (xprt->xp_pool->sp_rcache)
753 		replay_setreply(xprt->xp_pool->sp_rcache,
754 		    &rply, svc_getrpccaller(rqstp), NULL);
755 
756 	svc_sendreply_common(rqstp, &rply, NULL);
757 }
758 
759 /*
760  * Authentication error reply
761  */
762 void
763 svcerr_auth(struct svc_req *rqstp, enum auth_stat why)
764 {
765 	SVCXPRT *xprt = rqstp->rq_xprt;
766 	struct rpc_msg rply;
767 
768 	rply.rm_xid = rqstp->rq_xid;
769 	rply.rm_direction = REPLY;
770 	rply.rm_reply.rp_stat = MSG_DENIED;
771 	rply.rjcted_rply.rj_stat = AUTH_ERROR;
772 	rply.rjcted_rply.rj_why = why;
773 
774 	if (xprt->xp_pool->sp_rcache)
775 		replay_setreply(xprt->xp_pool->sp_rcache,
776 		    &rply, svc_getrpccaller(rqstp), NULL);
777 
778 	svc_sendreply_common(rqstp, &rply, NULL);
779 }
780 
781 /*
782  * Auth too weak error reply
783  */
784 void
785 svcerr_weakauth(struct svc_req *rqstp)
786 {
787 
788 	svcerr_auth(rqstp, AUTH_TOOWEAK);
789 }
790 
791 /*
792  * Program unavailable error reply
793  */
794 void
795 svcerr_noprog(struct svc_req *rqstp)
796 {
797 	SVCXPRT *xprt = rqstp->rq_xprt;
798 	struct rpc_msg rply;
799 
800 	rply.rm_xid = rqstp->rq_xid;
801 	rply.rm_direction = REPLY;
802 	rply.rm_reply.rp_stat = MSG_ACCEPTED;
803 	rply.acpted_rply.ar_verf = rqstp->rq_verf;
804 	rply.acpted_rply.ar_stat = PROG_UNAVAIL;
805 
806 	if (xprt->xp_pool->sp_rcache)
807 		replay_setreply(xprt->xp_pool->sp_rcache,
808 		    &rply, svc_getrpccaller(rqstp), NULL);
809 
810 	svc_sendreply_common(rqstp, &rply, NULL);
811 }
812 
813 /*
814  * Program version mismatch error reply
815  */
816 void
817 svcerr_progvers(struct svc_req *rqstp, rpcvers_t low_vers, rpcvers_t high_vers)
818 {
819 	SVCXPRT *xprt = rqstp->rq_xprt;
820 	struct rpc_msg rply;
821 
822 	rply.rm_xid = rqstp->rq_xid;
823 	rply.rm_direction = REPLY;
824 	rply.rm_reply.rp_stat = MSG_ACCEPTED;
825 	rply.acpted_rply.ar_verf = rqstp->rq_verf;
826 	rply.acpted_rply.ar_stat = PROG_MISMATCH;
827 	rply.acpted_rply.ar_vers.low = (uint32_t)low_vers;
828 	rply.acpted_rply.ar_vers.high = (uint32_t)high_vers;
829 
830 	if (xprt->xp_pool->sp_rcache)
831 		replay_setreply(xprt->xp_pool->sp_rcache,
832 		    &rply, svc_getrpccaller(rqstp), NULL);
833 
834 	svc_sendreply_common(rqstp, &rply, NULL);
835 }
836 
837 /*
838  * Allocate a new server transport structure. All fields are
839  * initialized to zero and xp_p3 is initialized to point at an
840  * extension structure to hold various flags and authentication
841  * parameters.
842  */
843 SVCXPRT *
844 svc_xprt_alloc()
845 {
846 	SVCXPRT *xprt;
847 	SVCXPRT_EXT *ext;
848 
849 	xprt = mem_alloc(sizeof(SVCXPRT));
850 	memset(xprt, 0, sizeof(SVCXPRT));
851 	ext = mem_alloc(sizeof(SVCXPRT_EXT));
852 	memset(ext, 0, sizeof(SVCXPRT_EXT));
853 	xprt->xp_p3 = ext;
854 	refcount_init(&xprt->xp_refs, 1);
855 
856 	return (xprt);
857 }
858 
859 /*
860  * Free a server transport structure.
861  */
862 void
863 svc_xprt_free(xprt)
864 	SVCXPRT *xprt;
865 {
866 
867 	mem_free(xprt->xp_p3, sizeof(SVCXPRT_EXT));
868 	mem_free(xprt, sizeof(SVCXPRT));
869 }
870 
871 /* ******************* SERVER INPUT STUFF ******************* */
872 
873 /*
874  * Read RPC requests from a transport and queue them to be
875  * executed. We handle authentication and replay cache replies here.
876  * Actually dispatching the RPC is deferred till svc_executereq.
877  */
878 static enum xprt_stat
879 svc_getreq(SVCXPRT *xprt, struct svc_req **rqstp_ret)
880 {
881 	SVCPOOL *pool = xprt->xp_pool;
882 	struct svc_req *r;
883 	struct rpc_msg msg;
884 	struct mbuf *args;
885 	struct svc_loss_callout *s;
886 	enum xprt_stat stat;
887 
888 	/* now receive msgs from xprtprt (support batch calls) */
889 	r = malloc(sizeof(*r), M_RPC, M_WAITOK|M_ZERO);
890 
891 	msg.rm_call.cb_cred.oa_base = r->rq_credarea;
892 	msg.rm_call.cb_verf.oa_base = &r->rq_credarea[MAX_AUTH_BYTES];
893 	r->rq_clntcred = &r->rq_credarea[2*MAX_AUTH_BYTES];
894 	if (SVC_RECV(xprt, &msg, &r->rq_addr, &args)) {
895 		enum auth_stat why;
896 
897 		/*
898 		 * Handle replays and authenticate before queuing the
899 		 * request to be executed.
900 		 */
901 		SVC_ACQUIRE(xprt);
902 		r->rq_xprt = xprt;
903 		if (pool->sp_rcache) {
904 			struct rpc_msg repmsg;
905 			struct mbuf *repbody;
906 			enum replay_state rs;
907 			rs = replay_find(pool->sp_rcache, &msg,
908 			    svc_getrpccaller(r), &repmsg, &repbody);
909 			switch (rs) {
910 			case RS_NEW:
911 				break;
912 			case RS_DONE:
913 				SVC_REPLY(xprt, &repmsg, r->rq_addr,
914 				    repbody, &r->rq_reply_seq);
915 				if (r->rq_addr) {
916 					free(r->rq_addr, M_SONAME);
917 					r->rq_addr = NULL;
918 				}
919 				m_freem(args);
920 				goto call_done;
921 
922 			default:
923 				m_freem(args);
924 				goto call_done;
925 			}
926 		}
927 
928 		r->rq_xid = msg.rm_xid;
929 		r->rq_prog = msg.rm_call.cb_prog;
930 		r->rq_vers = msg.rm_call.cb_vers;
931 		r->rq_proc = msg.rm_call.cb_proc;
932 		r->rq_size = sizeof(*r) + m_length(args, NULL);
933 		r->rq_args = args;
934 		if ((why = _authenticate(r, &msg)) != AUTH_OK) {
935 			/*
936 			 * RPCSEC_GSS uses this return code
937 			 * for requests that form part of its
938 			 * context establishment protocol and
939 			 * should not be dispatched to the
940 			 * application.
941 			 */
942 			if (why != RPCSEC_GSS_NODISPATCH)
943 				svcerr_auth(r, why);
944 			goto call_done;
945 		}
946 
947 		if (!SVCAUTH_UNWRAP(&r->rq_auth, &r->rq_args)) {
948 			svcerr_decode(r);
949 			goto call_done;
950 		}
951 
952 		/*
953 		 * Everything checks out, return request to caller.
954 		 */
955 		*rqstp_ret = r;
956 		r = NULL;
957 	}
958 call_done:
959 	if (r) {
960 		svc_freereq(r);
961 		r = NULL;
962 	}
963 	if ((stat = SVC_STAT(xprt)) == XPRT_DIED) {
964 		TAILQ_FOREACH(s, &pool->sp_lcallouts, slc_link)
965 			(*s->slc_dispatch)(xprt);
966 		xprt_unregister(xprt);
967 	}
968 
969 	return (stat);
970 }
971 
972 static void
973 svc_executereq(struct svc_req *rqstp)
974 {
975 	SVCXPRT *xprt = rqstp->rq_xprt;
976 	SVCPOOL *pool = xprt->xp_pool;
977 	int prog_found;
978 	rpcvers_t low_vers;
979 	rpcvers_t high_vers;
980 	struct svc_callout *s;
981 
982 	/* now match message with a registered service*/
983 	prog_found = FALSE;
984 	low_vers = (rpcvers_t) -1L;
985 	high_vers = (rpcvers_t) 0L;
986 	TAILQ_FOREACH(s, &pool->sp_callouts, sc_link) {
987 		if (s->sc_prog == rqstp->rq_prog) {
988 			if (s->sc_vers == rqstp->rq_vers) {
989 				/*
990 				 * We hand ownership of r to the
991 				 * dispatch method - they must call
992 				 * svc_freereq.
993 				 */
994 				(*s->sc_dispatch)(rqstp, xprt);
995 				return;
996 			}  /* found correct version */
997 			prog_found = TRUE;
998 			if (s->sc_vers < low_vers)
999 				low_vers = s->sc_vers;
1000 			if (s->sc_vers > high_vers)
1001 				high_vers = s->sc_vers;
1002 		}   /* found correct program */
1003 	}
1004 
1005 	/*
1006 	 * if we got here, the program or version
1007 	 * is not served ...
1008 	 */
1009 	if (prog_found)
1010 		svcerr_progvers(rqstp, low_vers, high_vers);
1011 	else
1012 		svcerr_noprog(rqstp);
1013 
1014 	svc_freereq(rqstp);
1015 }
1016 
1017 static void
1018 svc_checkidle(SVCGROUP *grp)
1019 {
1020 	SVCXPRT *xprt, *nxprt;
1021 	time_t timo;
1022 	struct svcxprt_list cleanup;
1023 
1024 	TAILQ_INIT(&cleanup);
1025 	TAILQ_FOREACH_SAFE(xprt, &grp->sg_xlist, xp_link, nxprt) {
1026 		/*
1027 		 * Only some transports have idle timers. Don't time
1028 		 * something out which is just waking up.
1029 		 */
1030 		if (!xprt->xp_idletimeout || xprt->xp_thread)
1031 			continue;
1032 
1033 		timo = xprt->xp_lastactive + xprt->xp_idletimeout;
1034 		if (time_uptime > timo) {
1035 			xprt_unregister_locked(xprt);
1036 			TAILQ_INSERT_TAIL(&cleanup, xprt, xp_link);
1037 		}
1038 	}
1039 
1040 	mtx_unlock(&grp->sg_lock);
1041 	TAILQ_FOREACH_SAFE(xprt, &cleanup, xp_link, nxprt) {
1042 		SVC_RELEASE(xprt);
1043 	}
1044 	mtx_lock(&grp->sg_lock);
1045 }
1046 
1047 static void
1048 svc_assign_waiting_sockets(SVCPOOL *pool)
1049 {
1050 	SVCGROUP *grp;
1051 	SVCXPRT *xprt;
1052 	int g;
1053 
1054 	for (g = 0; g < pool->sp_groupcount; g++) {
1055 		grp = &pool->sp_groups[g];
1056 		mtx_lock(&grp->sg_lock);
1057 		while ((xprt = TAILQ_FIRST(&grp->sg_active)) != NULL) {
1058 			if (xprt_assignthread(xprt))
1059 				TAILQ_REMOVE(&grp->sg_active, xprt, xp_alink);
1060 			else
1061 				break;
1062 		}
1063 		mtx_unlock(&grp->sg_lock);
1064 	}
1065 }
1066 
1067 static void
1068 svc_change_space_used(SVCPOOL *pool, long delta)
1069 {
1070 	unsigned long value;
1071 
1072 	value = atomic_fetchadd_long(&pool->sp_space_used, delta) + delta;
1073 	if (delta > 0) {
1074 		if (value >= pool->sp_space_high && !pool->sp_space_throttled) {
1075 			pool->sp_space_throttled = TRUE;
1076 			pool->sp_space_throttle_count++;
1077 		}
1078 		if (value > pool->sp_space_used_highest)
1079 			pool->sp_space_used_highest = value;
1080 	} else {
1081 		if (value < pool->sp_space_low && pool->sp_space_throttled) {
1082 			pool->sp_space_throttled = FALSE;
1083 			svc_assign_waiting_sockets(pool);
1084 		}
1085 	}
1086 }
1087 
1088 static bool_t
1089 svc_request_space_available(SVCPOOL *pool)
1090 {
1091 
1092 	if (pool->sp_space_throttled)
1093 		return (FALSE);
1094 	return (TRUE);
1095 }
1096 
1097 static void
1098 svc_run_internal(SVCGROUP *grp, bool_t ismaster)
1099 {
1100 	SVCPOOL *pool = grp->sg_pool;
1101 	SVCTHREAD *st, *stpref;
1102 	SVCXPRT *xprt;
1103 	enum xprt_stat stat;
1104 	struct svc_req *rqstp;
1105 	struct proc *p;
1106 	long sz;
1107 	int error;
1108 
1109 	st = mem_alloc(sizeof(*st));
1110 	mtx_init(&st->st_lock, "st_lock", NULL, MTX_DEF);
1111 	st->st_pool = pool;
1112 	st->st_xprt = NULL;
1113 	STAILQ_INIT(&st->st_reqs);
1114 	cv_init(&st->st_cond, "rpcsvc");
1115 
1116 	mtx_lock(&grp->sg_lock);
1117 
1118 	/*
1119 	 * If we are a new thread which was spawned to cope with
1120 	 * increased load, set the state back to SVCPOOL_ACTIVE.
1121 	 */
1122 	if (grp->sg_state == SVCPOOL_THREADSTARTING)
1123 		grp->sg_state = SVCPOOL_ACTIVE;
1124 
1125 	while (grp->sg_state != SVCPOOL_CLOSING) {
1126 		/*
1127 		 * Create new thread if requested.
1128 		 */
1129 		if (grp->sg_state == SVCPOOL_THREADWANTED) {
1130 			grp->sg_state = SVCPOOL_THREADSTARTING;
1131 			grp->sg_lastcreatetime = time_uptime;
1132 			mtx_unlock(&grp->sg_lock);
1133 			svc_new_thread(grp);
1134 			mtx_lock(&grp->sg_lock);
1135 			continue;
1136 		}
1137 
1138 		/*
1139 		 * Check for idle transports once per second.
1140 		 */
1141 		if (time_uptime > grp->sg_lastidlecheck) {
1142 			grp->sg_lastidlecheck = time_uptime;
1143 			svc_checkidle(grp);
1144 		}
1145 
1146 		xprt = st->st_xprt;
1147 		if (!xprt) {
1148 			/*
1149 			 * Enforce maxthreads count.
1150 			 */
1151 			if (grp->sg_threadcount > grp->sg_maxthreads)
1152 				break;
1153 
1154 			/*
1155 			 * Before sleeping, see if we can find an
1156 			 * active transport which isn't being serviced
1157 			 * by a thread.
1158 			 */
1159 			if (svc_request_space_available(pool) &&
1160 			    (xprt = TAILQ_FIRST(&grp->sg_active)) != NULL) {
1161 				TAILQ_REMOVE(&grp->sg_active, xprt, xp_alink);
1162 				SVC_ACQUIRE(xprt);
1163 				xprt->xp_thread = st;
1164 				st->st_xprt = xprt;
1165 				continue;
1166 			}
1167 
1168 			LIST_INSERT_HEAD(&grp->sg_idlethreads, st, st_ilink);
1169 			if (ismaster || (!ismaster &&
1170 			    grp->sg_threadcount > grp->sg_minthreads))
1171 				error = cv_timedwait_sig(&st->st_cond,
1172 				    &grp->sg_lock, 5 * hz);
1173 			else
1174 				error = cv_wait_sig(&st->st_cond,
1175 				    &grp->sg_lock);
1176 			if (st->st_xprt == NULL)
1177 				LIST_REMOVE(st, st_ilink);
1178 
1179 			/*
1180 			 * Reduce worker thread count when idle.
1181 			 */
1182 			if (error == EWOULDBLOCK) {
1183 				if (!ismaster
1184 				    && (grp->sg_threadcount
1185 					> grp->sg_minthreads)
1186 					&& !st->st_xprt)
1187 					break;
1188 			} else if (error != 0) {
1189 				KASSERT(error == EINTR || error == ERESTART,
1190 				    ("non-signal error %d", error));
1191 				mtx_unlock(&grp->sg_lock);
1192 				p = curproc;
1193 				PROC_LOCK(p);
1194 				if (P_SHOULDSTOP(p) ||
1195 				    (p->p_flag & P_TOTAL_STOP) != 0) {
1196 					thread_suspend_check(0);
1197 					PROC_UNLOCK(p);
1198 					mtx_lock(&grp->sg_lock);
1199 				} else {
1200 					PROC_UNLOCK(p);
1201 					svc_exit(pool);
1202 					mtx_lock(&grp->sg_lock);
1203 					break;
1204 				}
1205 			}
1206 			continue;
1207 		}
1208 		mtx_unlock(&grp->sg_lock);
1209 
1210 		/*
1211 		 * Drain the transport socket and queue up any RPCs.
1212 		 */
1213 		xprt->xp_lastactive = time_uptime;
1214 		do {
1215 			if (!svc_request_space_available(pool))
1216 				break;
1217 			rqstp = NULL;
1218 			stat = svc_getreq(xprt, &rqstp);
1219 			if (rqstp) {
1220 				svc_change_space_used(pool, rqstp->rq_size);
1221 				/*
1222 				 * See if the application has a preference
1223 				 * for some other thread.
1224 				 */
1225 				if (pool->sp_assign) {
1226 					stpref = pool->sp_assign(st, rqstp);
1227 					rqstp->rq_thread = stpref;
1228 					STAILQ_INSERT_TAIL(&stpref->st_reqs,
1229 					    rqstp, rq_link);
1230 					mtx_unlock(&stpref->st_lock);
1231 					if (stpref != st)
1232 						rqstp = NULL;
1233 				} else {
1234 					rqstp->rq_thread = st;
1235 					STAILQ_INSERT_TAIL(&st->st_reqs,
1236 					    rqstp, rq_link);
1237 				}
1238 			}
1239 		} while (rqstp == NULL && stat == XPRT_MOREREQS
1240 		    && grp->sg_state != SVCPOOL_CLOSING);
1241 
1242 		/*
1243 		 * Move this transport to the end of the active list to
1244 		 * ensure fairness when multiple transports are active.
1245 		 * If this was the last queued request, svc_getreq will end
1246 		 * up calling xprt_inactive to remove from the active list.
1247 		 */
1248 		mtx_lock(&grp->sg_lock);
1249 		xprt->xp_thread = NULL;
1250 		st->st_xprt = NULL;
1251 		if (xprt->xp_active) {
1252 			if (!svc_request_space_available(pool) ||
1253 			    !xprt_assignthread(xprt))
1254 				TAILQ_INSERT_TAIL(&grp->sg_active,
1255 				    xprt, xp_alink);
1256 		}
1257 		mtx_unlock(&grp->sg_lock);
1258 		SVC_RELEASE(xprt);
1259 
1260 		/*
1261 		 * Execute what we have queued.
1262 		 */
1263 		mtx_lock(&st->st_lock);
1264 		while ((rqstp = STAILQ_FIRST(&st->st_reqs)) != NULL) {
1265 			STAILQ_REMOVE_HEAD(&st->st_reqs, rq_link);
1266 			mtx_unlock(&st->st_lock);
1267 			sz = (long)rqstp->rq_size;
1268 			svc_executereq(rqstp);
1269 			svc_change_space_used(pool, -sz);
1270 			mtx_lock(&st->st_lock);
1271 		}
1272 		mtx_unlock(&st->st_lock);
1273 		mtx_lock(&grp->sg_lock);
1274 	}
1275 
1276 	if (st->st_xprt) {
1277 		xprt = st->st_xprt;
1278 		st->st_xprt = NULL;
1279 		SVC_RELEASE(xprt);
1280 	}
1281 	KASSERT(STAILQ_EMPTY(&st->st_reqs), ("stray reqs on exit"));
1282 	mtx_destroy(&st->st_lock);
1283 	cv_destroy(&st->st_cond);
1284 	mem_free(st, sizeof(*st));
1285 
1286 	grp->sg_threadcount--;
1287 	if (!ismaster)
1288 		wakeup(grp);
1289 	mtx_unlock(&grp->sg_lock);
1290 }
1291 
1292 static void
1293 svc_thread_start(void *arg)
1294 {
1295 
1296 	svc_run_internal((SVCGROUP *) arg, FALSE);
1297 	kthread_exit();
1298 }
1299 
1300 static void
1301 svc_new_thread(SVCGROUP *grp)
1302 {
1303 	SVCPOOL *pool = grp->sg_pool;
1304 	struct thread *td;
1305 
1306 	mtx_lock(&grp->sg_lock);
1307 	grp->sg_threadcount++;
1308 	mtx_unlock(&grp->sg_lock);
1309 	kthread_add(svc_thread_start, grp, pool->sp_proc, &td, 0, 0,
1310 	    "%s: service", pool->sp_name);
1311 }
1312 
1313 void
1314 svc_run(SVCPOOL *pool)
1315 {
1316 	int g, i;
1317 	struct proc *p;
1318 	struct thread *td;
1319 	SVCGROUP *grp;
1320 
1321 	p = curproc;
1322 	td = curthread;
1323 	snprintf(td->td_name, sizeof(td->td_name),
1324 	    "%s: master", pool->sp_name);
1325 	pool->sp_state = SVCPOOL_ACTIVE;
1326 	pool->sp_proc = p;
1327 
1328 	/* Choose group count based on number of threads and CPUs. */
1329 	pool->sp_groupcount = max(1, min(SVC_MAXGROUPS,
1330 	    min(pool->sp_maxthreads / 2, mp_ncpus) / 6));
1331 	for (g = 0; g < pool->sp_groupcount; g++) {
1332 		grp = &pool->sp_groups[g];
1333 		grp->sg_minthreads = max(1,
1334 		    pool->sp_minthreads / pool->sp_groupcount);
1335 		grp->sg_maxthreads = max(1,
1336 		    pool->sp_maxthreads / pool->sp_groupcount);
1337 		grp->sg_lastcreatetime = time_uptime;
1338 	}
1339 
1340 	/* Starting threads */
1341 	pool->sp_groups[0].sg_threadcount++;
1342 	for (g = 0; g < pool->sp_groupcount; g++) {
1343 		grp = &pool->sp_groups[g];
1344 		for (i = ((g == 0) ? 1 : 0); i < grp->sg_minthreads; i++)
1345 			svc_new_thread(grp);
1346 	}
1347 	svc_run_internal(&pool->sp_groups[0], TRUE);
1348 
1349 	/* Waiting for threads to stop. */
1350 	for (g = 0; g < pool->sp_groupcount; g++) {
1351 		grp = &pool->sp_groups[g];
1352 		mtx_lock(&grp->sg_lock);
1353 		while (grp->sg_threadcount > 0)
1354 			msleep(grp, &grp->sg_lock, 0, "svcexit", 0);
1355 		mtx_unlock(&grp->sg_lock);
1356 	}
1357 }
1358 
1359 void
1360 svc_exit(SVCPOOL *pool)
1361 {
1362 	SVCGROUP *grp;
1363 	SVCTHREAD *st;
1364 	int g;
1365 
1366 	pool->sp_state = SVCPOOL_CLOSING;
1367 	for (g = 0; g < pool->sp_groupcount; g++) {
1368 		grp = &pool->sp_groups[g];
1369 		mtx_lock(&grp->sg_lock);
1370 		if (grp->sg_state != SVCPOOL_CLOSING) {
1371 			grp->sg_state = SVCPOOL_CLOSING;
1372 			LIST_FOREACH(st, &grp->sg_idlethreads, st_ilink)
1373 				cv_signal(&st->st_cond);
1374 		}
1375 		mtx_unlock(&grp->sg_lock);
1376 	}
1377 }
1378 
1379 bool_t
1380 svc_getargs(struct svc_req *rqstp, xdrproc_t xargs, void *args)
1381 {
1382 	struct mbuf *m;
1383 	XDR xdrs;
1384 	bool_t stat;
1385 
1386 	m = rqstp->rq_args;
1387 	rqstp->rq_args = NULL;
1388 
1389 	xdrmbuf_create(&xdrs, m, XDR_DECODE);
1390 	stat = xargs(&xdrs, args);
1391 	XDR_DESTROY(&xdrs);
1392 
1393 	return (stat);
1394 }
1395 
1396 bool_t
1397 svc_freeargs(struct svc_req *rqstp, xdrproc_t xargs, void *args)
1398 {
1399 	XDR xdrs;
1400 
1401 	if (rqstp->rq_addr) {
1402 		free(rqstp->rq_addr, M_SONAME);
1403 		rqstp->rq_addr = NULL;
1404 	}
1405 
1406 	xdrs.x_op = XDR_FREE;
1407 	return (xargs(&xdrs, args));
1408 }
1409 
1410 void
1411 svc_freereq(struct svc_req *rqstp)
1412 {
1413 	SVCTHREAD *st;
1414 	SVCPOOL *pool;
1415 
1416 	st = rqstp->rq_thread;
1417 	if (st) {
1418 		pool = st->st_pool;
1419 		if (pool->sp_done)
1420 			pool->sp_done(st, rqstp);
1421 	}
1422 
1423 	if (rqstp->rq_auth.svc_ah_ops)
1424 		SVCAUTH_RELEASE(&rqstp->rq_auth);
1425 
1426 	if (rqstp->rq_xprt) {
1427 		SVC_RELEASE(rqstp->rq_xprt);
1428 	}
1429 
1430 	if (rqstp->rq_addr)
1431 		free(rqstp->rq_addr, M_SONAME);
1432 
1433 	if (rqstp->rq_args)
1434 		m_freem(rqstp->rq_args);
1435 
1436 	free(rqstp, M_RPC);
1437 }
1438