aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2016-06-24 10:55:51 -0400
committerJ. Bruce Fields <bfields@redhat.com>2016-07-13 15:53:49 -0400
commit637600f3ffbf1af0c2efd5587ac357b900c4c999 (patch)
treeceb9f96dd1ecb0a03958850446cc3c79aa010630 /net
parentff3ac5c3dc2323ba54c3d9ef30ef4942a71b251d (diff)
SUNRPC: Change TCP socket space reservation
The current server rpc tcp code attempts to predict how much writeable socket space will be available to a given RPC call before accepting it for processing. On a 40GigE network, we've found this throttles individual clients long before the network or disk is saturated. The server may handle more clients easily, but the bandwidth of individual clients is still artificially limited. Instead of trying (and failing) to predict how much writeable socket space will be available to the RPC call, just fall back to the simple model of deferring processing until the socket is uncongested. This may increase the risk of fast clients starving slower clients; in such cases, the previous patch allows setting a hard per-connection limit. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/svcsock.c47
1 files changed, 4 insertions, 43 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 338d6fe1103d..bc3ef0734f2f 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -431,43 +431,11 @@ static void svc_write_space(struct sock *sk)
431 431
432static int svc_tcp_has_wspace(struct svc_xprt *xprt) 432static int svc_tcp_has_wspace(struct svc_xprt *xprt)
433{ 433{
434 struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt); 434 struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt);
435 struct svc_serv *serv = svsk->sk_xprt.xpt_server;
436 int required;
437 435
438 if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) 436 if (test_bit(XPT_LISTENER, &xprt->xpt_flags))
439 return 1; 437 return 1;
440 required = atomic_read(&xprt->xpt_reserved) + serv->sv_max_mesg; 438 return !test_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
441 if (sk_stream_wspace(svsk->sk_sk) >= required ||
442 (sk_stream_min_wspace(svsk->sk_sk) == 0 &&
443 atomic_read(&xprt->xpt_reserved) == 0))
444 return 1;
445 set_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
446 return 0;
447}
448
449static void svc_tcp_write_space(struct sock *sk)
450{
451 struct svc_sock *svsk = (struct svc_sock *)(sk->sk_user_data);
452 struct socket *sock = sk->sk_socket;
453
454 if (!svsk)
455 return;
456
457 if (!sk_stream_is_writeable(sk) || !sock)
458 return;
459 if (svc_tcp_has_wspace(&svsk->sk_xprt)) {
460 clear_bit(SOCK_NOSPACE, &sock->flags);
461 svc_write_space(sk);
462 }
463}
464
465static void svc_tcp_adjust_wspace(struct svc_xprt *xprt)
466{
467 struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt);
468
469 if (svc_tcp_has_wspace(xprt))
470 clear_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
471} 439}
472 440
473/* 441/*
@@ -1272,7 +1240,6 @@ static struct svc_xprt_ops svc_tcp_ops = {
1272 .xpo_has_wspace = svc_tcp_has_wspace, 1240 .xpo_has_wspace = svc_tcp_has_wspace,
1273 .xpo_accept = svc_tcp_accept, 1241 .xpo_accept = svc_tcp_accept,
1274 .xpo_secure_port = svc_sock_secure_port, 1242 .xpo_secure_port = svc_sock_secure_port,
1275 .xpo_adjust_wspace = svc_tcp_adjust_wspace,
1276}; 1243};
1277 1244
1278static struct svc_xprt_class svc_tcp_class = { 1245static struct svc_xprt_class svc_tcp_class = {
@@ -1313,7 +1280,7 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)
1313 dprintk("setting up TCP socket for reading\n"); 1280 dprintk("setting up TCP socket for reading\n");
1314 sk->sk_state_change = svc_tcp_state_change; 1281 sk->sk_state_change = svc_tcp_state_change;
1315 sk->sk_data_ready = svc_data_ready; 1282 sk->sk_data_ready = svc_data_ready;
1316 sk->sk_write_space = svc_tcp_write_space; 1283 sk->sk_write_space = svc_write_space;
1317 1284
1318 svsk->sk_reclen = 0; 1285 svsk->sk_reclen = 0;
1319 svsk->sk_tcplen = 0; 1286 svsk->sk_tcplen = 0;
@@ -1383,14 +1350,8 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
1383 /* Initialize the socket */ 1350 /* Initialize the socket */
1384 if (sock->type == SOCK_DGRAM) 1351 if (sock->type == SOCK_DGRAM)
1385 svc_udp_init(svsk, serv); 1352 svc_udp_init(svsk, serv);
1386 else { 1353 else
1387 /* initialise setting must have enough space to
1388 * receive and respond to one request.
1389 */
1390 svc_sock_setbufsize(svsk->sk_sock, 4 * serv->sv_max_mesg,
1391 4 * serv->sv_max_mesg);
1392 svc_tcp_init(svsk, serv); 1354 svc_tcp_init(svsk, serv);
1393 }
1394 1355
1395 dprintk("svc: svc_setup_socket created %p (inet %p)\n", 1356 dprintk("svc: svc_setup_socket created %p (inet %p)\n",
1396 svsk, svsk->sk_sk); 1357 svsk, svsk->sk_sk);