Changeset View
Changeset View
Standalone View
Standalone View
head/sys/rpc/svc.c
Show First 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | |||||
#define SVC_VERSQUIET 0x0001 /* keep quiet about vers mismatch */ | #define SVC_VERSQUIET 0x0001 /* keep quiet about vers mismatch */ | ||||
#define version_keepquiet(xp) (SVC_EXT(xp)->xp_flags & SVC_VERSQUIET) | #define version_keepquiet(xp) (SVC_EXT(xp)->xp_flags & SVC_VERSQUIET) | ||||
static struct svc_callout *svc_find(SVCPOOL *pool, rpcprog_t, rpcvers_t, | static struct svc_callout *svc_find(SVCPOOL *pool, rpcprog_t, rpcvers_t, | ||||
char *); | char *); | ||||
static void svc_new_thread(SVCGROUP *grp); | static void svc_new_thread(SVCGROUP *grp); | ||||
static void xprt_unregister_locked(SVCXPRT *xprt); | static void xprt_unregister_locked(SVCXPRT *xprt); | ||||
static void svc_change_space_used(SVCPOOL *pool, int delta); | static void svc_change_space_used(SVCPOOL *pool, long delta); | ||||
static bool_t svc_request_space_available(SVCPOOL *pool); | static bool_t svc_request_space_available(SVCPOOL *pool); | ||||
/* *************** SVCXPRT related stuff **************** */ | /* *************** SVCXPRT related stuff **************** */ | ||||
static int svcpool_minthread_sysctl(SYSCTL_HANDLER_ARGS); | static int svcpool_minthread_sysctl(SYSCTL_HANDLER_ARGS); | ||||
static int svcpool_maxthread_sysctl(SYSCTL_HANDLER_ARGS); | static int svcpool_maxthread_sysctl(SYSCTL_HANDLER_ARGS); | ||||
static int svcpool_threads_sysctl(SYSCTL_HANDLER_ARGS); | static int svcpool_threads_sysctl(SYSCTL_HANDLER_ARGS); | ||||
Show All 23 Lines | for (g = 0; g < SVC_MAXGROUPS; g++) { | ||||
TAILQ_INIT(&grp->sg_xlist); | TAILQ_INIT(&grp->sg_xlist); | ||||
TAILQ_INIT(&grp->sg_active); | TAILQ_INIT(&grp->sg_active); | ||||
LIST_INIT(&grp->sg_idlethreads); | LIST_INIT(&grp->sg_idlethreads); | ||||
grp->sg_minthreads = 1; | grp->sg_minthreads = 1; | ||||
grp->sg_maxthreads = 1; | grp->sg_maxthreads = 1; | ||||
} | } | ||||
/* | /* | ||||
* Don't use more than a quarter of mbuf clusters or more than | * Don't use more than a quarter of mbuf clusters. Nota bene: | ||||
* 45Mb buffering requests. | * nmbclusters is an int, but nmbclusters*MCLBYTES may overflow | ||||
* on LP64 architectures, so cast to u_long to avoid undefined | |||||
* behavior. (ILP32 architectures cannot have nmbclusters | |||||
* large enough to overflow for other reasons.) | |||||
*/ | */ | ||||
pool->sp_space_high = nmbclusters * MCLBYTES / 4; | pool->sp_space_high = (u_long)nmbclusters * MCLBYTES / 4; | ||||
if (pool->sp_space_high > 45 << 20) | pool->sp_space_low = (pool->sp_space_high / 3) * 2; | ||||
pool->sp_space_high = 45 << 20; | |||||
pool->sp_space_low = 2 * pool->sp_space_high / 3; | |||||
sysctl_ctx_init(&pool->sp_sysctl); | sysctl_ctx_init(&pool->sp_sysctl); | ||||
if (sysctl_base) { | if (sysctl_base) { | ||||
SYSCTL_ADD_PROC(&pool->sp_sysctl, sysctl_base, OID_AUTO, | SYSCTL_ADD_PROC(&pool->sp_sysctl, sysctl_base, OID_AUTO, | ||||
"minthreads", CTLTYPE_INT | CTLFLAG_RW, | "minthreads", CTLTYPE_INT | CTLFLAG_RW, | ||||
pool, 0, svcpool_minthread_sysctl, "I", | pool, 0, svcpool_minthread_sysctl, "I", | ||||
"Minimal number of threads"); | "Minimal number of threads"); | ||||
SYSCTL_ADD_PROC(&pool->sp_sysctl, sysctl_base, OID_AUTO, | SYSCTL_ADD_PROC(&pool->sp_sysctl, sysctl_base, OID_AUTO, | ||||
"maxthreads", CTLTYPE_INT | CTLFLAG_RW, | "maxthreads", CTLTYPE_INT | CTLFLAG_RW, | ||||
pool, 0, svcpool_maxthread_sysctl, "I", | pool, 0, svcpool_maxthread_sysctl, "I", | ||||
"Maximal number of threads"); | "Maximal number of threads"); | ||||
SYSCTL_ADD_PROC(&pool->sp_sysctl, sysctl_base, OID_AUTO, | SYSCTL_ADD_PROC(&pool->sp_sysctl, sysctl_base, OID_AUTO, | ||||
"threads", CTLTYPE_INT | CTLFLAG_RD, | "threads", CTLTYPE_INT | CTLFLAG_RD, | ||||
pool, 0, svcpool_threads_sysctl, "I", | pool, 0, svcpool_threads_sysctl, "I", | ||||
"Current number of threads"); | "Current number of threads"); | ||||
SYSCTL_ADD_INT(&pool->sp_sysctl, sysctl_base, OID_AUTO, | SYSCTL_ADD_INT(&pool->sp_sysctl, sysctl_base, OID_AUTO, | ||||
"groups", CTLFLAG_RD, &pool->sp_groupcount, 0, | "groups", CTLFLAG_RD, &pool->sp_groupcount, 0, | ||||
"Number of thread groups"); | "Number of thread groups"); | ||||
SYSCTL_ADD_UINT(&pool->sp_sysctl, sysctl_base, OID_AUTO, | SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO, | ||||
"request_space_used", CTLFLAG_RD, | "request_space_used", CTLFLAG_RD, | ||||
&pool->sp_space_used, 0, | &pool->sp_space_used, | ||||
"Space in parsed but not handled requests."); | "Space in parsed but not handled requests."); | ||||
SYSCTL_ADD_UINT(&pool->sp_sysctl, sysctl_base, OID_AUTO, | SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO, | ||||
"request_space_used_highest", CTLFLAG_RD, | "request_space_used_highest", CTLFLAG_RD, | ||||
&pool->sp_space_used_highest, 0, | &pool->sp_space_used_highest, | ||||
"Highest space used since reboot."); | "Highest space used since reboot."); | ||||
SYSCTL_ADD_UINT(&pool->sp_sysctl, sysctl_base, OID_AUTO, | SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO, | ||||
"request_space_high", CTLFLAG_RW, | "request_space_high", CTLFLAG_RW, | ||||
&pool->sp_space_high, 0, | &pool->sp_space_high, | ||||
"Maximum space in parsed but not handled requests."); | "Maximum space in parsed but not handled requests."); | ||||
SYSCTL_ADD_UINT(&pool->sp_sysctl, sysctl_base, OID_AUTO, | SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO, | ||||
"request_space_low", CTLFLAG_RW, | "request_space_low", CTLFLAG_RW, | ||||
&pool->sp_space_low, 0, | &pool->sp_space_low, | ||||
"Low water mark for request space."); | "Low water mark for request space."); | ||||
SYSCTL_ADD_INT(&pool->sp_sysctl, sysctl_base, OID_AUTO, | SYSCTL_ADD_INT(&pool->sp_sysctl, sysctl_base, OID_AUTO, | ||||
"request_space_throttled", CTLFLAG_RD, | "request_space_throttled", CTLFLAG_RD, | ||||
&pool->sp_space_throttled, 0, | &pool->sp_space_throttled, 0, | ||||
"Whether nfs requests are currently throttled"); | "Whether nfs requests are currently throttled"); | ||||
SYSCTL_ADD_INT(&pool->sp_sysctl, sysctl_base, OID_AUTO, | SYSCTL_ADD_INT(&pool->sp_sysctl, sysctl_base, OID_AUTO, | ||||
▲ Show 20 Lines • Show All 891 Lines • ▼ Show 20 Lines | while ((xprt = TAILQ_FIRST(&grp->sg_active)) != NULL) { | ||||
else | else | ||||
break; | break; | ||||
} | } | ||||
mtx_unlock(&grp->sg_lock); | mtx_unlock(&grp->sg_lock); | ||||
} | } | ||||
} | } | ||||
static void | static void | ||||
svc_change_space_used(SVCPOOL *pool, int delta) | svc_change_space_used(SVCPOOL *pool, long delta) | ||||
{ | { | ||||
unsigned int value; | unsigned long value; | ||||
value = atomic_fetchadd_int(&pool->sp_space_used, delta) + delta; | value = atomic_fetchadd_long(&pool->sp_space_used, delta) + delta; | ||||
if (delta > 0) { | if (delta > 0) { | ||||
if (value >= pool->sp_space_high && !pool->sp_space_throttled) { | if (value >= pool->sp_space_high && !pool->sp_space_throttled) { | ||||
pool->sp_space_throttled = TRUE; | pool->sp_space_throttled = TRUE; | ||||
pool->sp_space_throttle_count++; | pool->sp_space_throttle_count++; | ||||
} | } | ||||
if (value > pool->sp_space_used_highest) | if (value > pool->sp_space_used_highest) | ||||
pool->sp_space_used_highest = value; | pool->sp_space_used_highest = value; | ||||
} else { | } else { | ||||
Show All 17 Lines | |||||
svc_run_internal(SVCGROUP *grp, bool_t ismaster) | svc_run_internal(SVCGROUP *grp, bool_t ismaster) | ||||
{ | { | ||||
SVCPOOL *pool = grp->sg_pool; | SVCPOOL *pool = grp->sg_pool; | ||||
SVCTHREAD *st, *stpref; | SVCTHREAD *st, *stpref; | ||||
SVCXPRT *xprt; | SVCXPRT *xprt; | ||||
enum xprt_stat stat; | enum xprt_stat stat; | ||||
struct svc_req *rqstp; | struct svc_req *rqstp; | ||||
struct proc *p; | struct proc *p; | ||||
size_t sz; | long sz; | ||||
int error; | int error; | ||||
st = mem_alloc(sizeof(*st)); | st = mem_alloc(sizeof(*st)); | ||||
mtx_init(&st->st_lock, "st_lock", NULL, MTX_DEF); | mtx_init(&st->st_lock, "st_lock", NULL, MTX_DEF); | ||||
st->st_pool = pool; | st->st_pool = pool; | ||||
st->st_xprt = NULL; | st->st_xprt = NULL; | ||||
STAILQ_INIT(&st->st_reqs); | STAILQ_INIT(&st->st_reqs); | ||||
cv_init(&st->st_cond, "rpcsvc"); | cv_init(&st->st_cond, "rpcsvc"); | ||||
▲ Show 20 Lines • Show All 140 Lines • ▼ Show 20 Lines | if (xprt->xp_active) { | ||||
xprt, xp_alink); | xprt, xp_alink); | ||||
} | } | ||||
mtx_unlock(&grp->sg_lock); | mtx_unlock(&grp->sg_lock); | ||||
SVC_RELEASE(xprt); | SVC_RELEASE(xprt); | ||||
/* | /* | ||||
* Execute what we have queued. | * Execute what we have queued. | ||||
*/ | */ | ||||
sz = 0; | |||||
mtx_lock(&st->st_lock); | mtx_lock(&st->st_lock); | ||||
while ((rqstp = STAILQ_FIRST(&st->st_reqs)) != NULL) { | while ((rqstp = STAILQ_FIRST(&st->st_reqs)) != NULL) { | ||||
STAILQ_REMOVE_HEAD(&st->st_reqs, rq_link); | STAILQ_REMOVE_HEAD(&st->st_reqs, rq_link); | ||||
mtx_unlock(&st->st_lock); | mtx_unlock(&st->st_lock); | ||||
sz += rqstp->rq_size; | sz = (long)rqstp->rq_size; | ||||
svc_executereq(rqstp); | svc_executereq(rqstp); | ||||
svc_change_space_used(pool, -sz); | |||||
mtx_lock(&st->st_lock); | mtx_lock(&st->st_lock); | ||||
} | } | ||||
mtx_unlock(&st->st_lock); | mtx_unlock(&st->st_lock); | ||||
svc_change_space_used(pool, -sz); | |||||
mtx_lock(&grp->sg_lock); | mtx_lock(&grp->sg_lock); | ||||
} | } | ||||
if (st->st_xprt) { | if (st->st_xprt) { | ||||
xprt = st->st_xprt; | xprt = st->st_xprt; | ||||
st->st_xprt = NULL; | st->st_xprt = NULL; | ||||
SVC_RELEASE(xprt); | SVC_RELEASE(xprt); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 155 Lines • Show Last 20 Lines |