Commit 103b47f1 authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] PATCH - kNFSd - Remove flowcontrol problems with lockd/tcp

The sunrpc/tcp layer currently allocates some resources linearly with
number of server threads.  This causes problems when there are very
small numbers of threads (e.g. lockd with one thread), so this patch
adds a small constant to the number of threads before calculating
resoures to allocate.

This patch also provide proper upper-limits for the response sizes for
lockd requests, so resources are not over-allocated.

Together these resolve problems with heavy lockd load over tcp.
parent fb91d591
...@@ -537,31 +537,35 @@ struct nlm_void { int dummy; }; ...@@ -537,31 +537,35 @@ struct nlm_void { int dummy; };
0, \ 0, \
respsize, \ respsize, \
} }
#define Ck (1+8) /* cookie */
#define No (1+1024/4) /* netobj */
#define St 1 /* status */
#define Rg 4 /* range (offset + length) */
struct svc_procedure nlmsvc_procedures4[] = { struct svc_procedure nlmsvc_procedures4[] = {
PROC(null, void, void, void, void, 0), PROC(null, void, void, void, void, 1),
PROC(test, testargs, testres, args, res, 0), PROC(test, testargs, testres, args, res, Ck+St+2+No+Rg),
PROC(lock, lockargs, res, args, res, 0), PROC(lock, lockargs, res, args, res, Ck+St),
PROC(cancel, cancargs, res, args, res, 0), PROC(cancel, cancargs, res, args, res, Ck+St),
PROC(unlock, unlockargs, res, args, res, 0), PROC(unlock, unlockargs, res, args, res, Ck+St),
PROC(granted, testargs, res, args, res, 0), PROC(granted, testargs, res, args, res, Ck+St),
PROC(test_msg, testargs, norep, args, void, 0), PROC(test_msg, testargs, norep, args, void, 1),
PROC(lock_msg, lockargs, norep, args, void, 0), PROC(lock_msg, lockargs, norep, args, void, 1),
PROC(cancel_msg, cancargs, norep, args, void, 0), PROC(cancel_msg, cancargs, norep, args, void, 1),
PROC(unlock_msg, unlockargs, norep, args, void, 0), PROC(unlock_msg, unlockargs, norep, args, void, 1),
PROC(granted_msg, testargs, norep, args, void, 0), PROC(granted_msg, testargs, norep, args, void, 1),
PROC(test_res, testres, norep, res, void, 0), PROC(test_res, testres, norep, res, void, 1),
PROC(lock_res, lockres, norep, res, void, 0), PROC(lock_res, lockres, norep, res, void, 1),
PROC(cancel_res, cancelres, norep, res, void, 0), PROC(cancel_res, cancelres, norep, res, void, 1),
PROC(unlock_res, unlockres, norep, res, void, 0), PROC(unlock_res, unlockres, norep, res, void, 1),
PROC(granted_res, grantedres, norep, res, void, 0), PROC(granted_res, grantedres, norep, res, void, 1),
/* statd callback */ /* statd callback */
PROC(sm_notify, reboot, void, reboot, void, 0), PROC(sm_notify, reboot, void, reboot, void, 1),
PROC(none, void, void, void, void, 0), PROC(none, void, void, void, void, 0),
PROC(none, void, void, void, void, 0), PROC(none, void, void, void, void, 0),
PROC(none, void, void, void, void, 0), PROC(none, void, void, void, void, 0),
PROC(share, shareargs, shareres, args, res, 0), PROC(share, shareargs, shareres, args, res, Ck+St+1),
PROC(unshare, shareargs, shareres, args, res, 0), PROC(unshare, shareargs, shareres, args, res, Ck+St+1),
PROC(nm_lock, lockargs, res, args, res, 0), PROC(nm_lock, lockargs, res, args, res, Ck+St),
PROC(free_all, notify, void, args, void, 0), PROC(free_all, notify, void, args, void, 1),
}; };
...@@ -565,31 +565,37 @@ struct nlm_void { int dummy; }; ...@@ -565,31 +565,37 @@ struct nlm_void { int dummy; };
0, \ 0, \
respsize, \ respsize, \
} }
#define Ck (1+8) /* cookie */
#define St 1 /* status */
#define No (1+1024/4) /* Net Obj */
#define Rg 2 /* range - offset + size */
struct svc_procedure nlmsvc_procedures[] = { struct svc_procedure nlmsvc_procedures[] = {
PROC(null, void, void, void, void, 0), PROC(null, void, void, void, void, 1),
PROC(test, testargs, testres, args, res, 0), PROC(test, testargs, testres, args, res, Ck+St+2+No+Rg),
PROC(lock, lockargs, res, args, res, 0), PROC(lock, lockargs, res, args, res, Ck+St),
PROC(cancel, cancargs, res, args, res, 0), PROC(cancel, cancargs, res, args, res, Ck+St),
PROC(unlock, unlockargs, res, args, res, 0), PROC(unlock, unlockargs, res, args, res, Ck+St),
PROC(granted, testargs, res, args, res, 0), PROC(granted, testargs, res, args, res, Ck+St),
PROC(test_msg, testargs, norep, args, void, 0), PROC(test_msg, testargs, norep, args, void, 1),
PROC(lock_msg, lockargs, norep, args, void, 0), PROC(lock_msg, lockargs, norep, args, void, 1),
PROC(cancel_msg, cancargs, norep, args, void, 0), PROC(cancel_msg, cancargs, norep, args, void, 1),
PROC(unlock_msg, unlockargs, norep, args, void, 0), PROC(unlock_msg, unlockargs, norep, args, void, 1),
PROC(granted_msg, testargs, norep, args, void, 0), PROC(granted_msg, testargs, norep, args, void, 1),
PROC(test_res, testres, norep, res, void, 0), PROC(test_res, testres, norep, res, void, 1),
PROC(lock_res, lockres, norep, res, void, 0), PROC(lock_res, lockres, norep, res, void, 1),
PROC(cancel_res, cancelres, norep, res, void, 0), PROC(cancel_res, cancelres, norep, res, void, 1),
PROC(unlock_res, unlockres, norep, res, void, 0), PROC(unlock_res, unlockres, norep, res, void, 1),
PROC(granted_res, grantedres, norep, res, void, 0), PROC(granted_res, grantedres, norep, res, void, 1),
/* statd callback */ /* statd callback */
PROC(sm_notify, reboot, void, reboot, void, 0), PROC(sm_notify, reboot, void, reboot, void, 1),
PROC(none, void, void, void, void, 0), PROC(none, void, void, void, void, 1),
PROC(none, void, void, void, void, 0), PROC(none, void, void, void, void, 1),
PROC(none, void, void, void, void, 0), PROC(none, void, void, void, void, 1),
PROC(share, shareargs, shareres, args, res, 0), PROC(share, shareargs, shareres, args, res, Ck+St+1),
PROC(unshare, shareargs, shareres, args, res, 0), PROC(unshare, shareargs, shareres, args, res, Ck+St+1),
PROC(nm_lock, lockargs, res, args, res, 0), PROC(nm_lock, lockargs, res, args, res, Ck+St),
PROC(free_all, notify, void, args, void, 0), PROC(free_all, notify, void, args, void, 0),
}; };
...@@ -710,7 +710,7 @@ svc_tcp_accept(struct svc_sock *svsk) ...@@ -710,7 +710,7 @@ svc_tcp_accept(struct svc_sock *svsk)
* We randomly choose between newest and oldest (in terms * We randomly choose between newest and oldest (in terms
* of recent activity) and drop it. * of recent activity) and drop it.
*/ */
if (serv->sv_tmpcnt > serv->sv_nrthreads*5) { if (serv->sv_tmpcnt > (serv->sv_nrthreads+3)*5) {
struct svc_sock *svsk = NULL; struct svc_sock *svsk = NULL;
spin_lock_bh(&serv->sv_lock); spin_lock_bh(&serv->sv_lock);
if (!list_empty(&serv->sv_tempsocks)) { if (!list_empty(&serv->sv_tempsocks)) {
...@@ -924,7 +924,7 @@ svc_tcp_init(struct svc_sock *svsk) ...@@ -924,7 +924,7 @@ svc_tcp_init(struct svc_sock *svsk)
* as soon a a complete request arrives. * as soon a a complete request arrives.
*/ */
svc_sock_setbufsize(svsk->sk_sock, svc_sock_setbufsize(svsk->sk_sock,
svsk->sk_server->sv_nrthreads * (svsk->sk_server->sv_nrthreads+3) *
svsk->sk_server->sv_bufsz, svsk->sk_server->sv_bufsz,
3 * svsk->sk_server->sv_bufsz); 3 * svsk->sk_server->sv_bufsz);
} }
...@@ -966,7 +966,7 @@ svc_sock_update_bufs(struct svc_serv *serv) ...@@ -966,7 +966,7 @@ svc_sock_update_bufs(struct svc_serv *serv)
if (sock->type == SOCK_STREAM) { if (sock->type == SOCK_STREAM) {
/* See svc_tcp_init above for rationale on buffer sizes */ /* See svc_tcp_init above for rationale on buffer sizes */
svc_sock_setbufsize(sock, svc_sock_setbufsize(sock,
serv->sv_nrthreads * (serv->sv_nrthreads+3) *
serv->sv_bufsz, serv->sv_bufsz,
3 * serv->sv_bufsz); 3 * serv->sv_bufsz);
} else } else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment