diff options
Diffstat (limited to 'net/sunrpc/svc_xprt.c')
-rw-r--r-- | net/sunrpc/svc_xprt.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index bf5b5cdafebf..3fe4f1004278 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -515,8 +515,10 @@ int svc_port_is_privileged(struct sockaddr *sin) | |||
515 | } | 515 | } |
516 | 516 | ||
517 | /* | 517 | /* |
518 | * Make sure that we don't have too many active connections. If we | 518 | * Make sure that we don't have too many active connections. If we have, |
519 | * have, something must be dropped. | 519 | * something must be dropped. It's not clear what will happen if we allow |
520 | * "too many" connections, but when dealing with network-facing software, | ||
521 | * we have to code defensively. Here we do that by imposing hard limits. | ||
520 | * | 522 | * |
521 | * There's no point in trying to do random drop here for DoS | 523 | * There's no point in trying to do random drop here for DoS |
522 | * prevention. The NFS clients does 1 reconnect in 15 seconds. An | 524 | * prevention. The NFS clients does 1 reconnect in 15 seconds. An |
@@ -525,19 +527,27 @@ int svc_port_is_privileged(struct sockaddr *sin) | |||
525 | * The only somewhat efficient mechanism would be if drop old | 527 | * The only somewhat efficient mechanism would be if drop old |
526 | * connections from the same IP first. But right now we don't even | 528 | * connections from the same IP first. But right now we don't even |
527 | * record the client IP in svc_sock. | 529 | * record the client IP in svc_sock. |
530 | * | ||
531 | * single-threaded services that expect a lot of clients will probably | ||
532 | * need to set sv_maxconn to override the default value which is based | ||
533 | * on the number of threads | ||
528 | */ | 534 | */ |
529 | static void svc_check_conn_limits(struct svc_serv *serv) | 535 | static void svc_check_conn_limits(struct svc_serv *serv) |
530 | { | 536 | { |
531 | if (serv->sv_tmpcnt > (serv->sv_nrthreads+3)*20) { | 537 | unsigned int limit = serv->sv_maxconn ? serv->sv_maxconn : |
538 | (serv->sv_nrthreads+3) * 20; | ||
539 | |||
540 | if (serv->sv_tmpcnt > limit) { | ||
532 | struct svc_xprt *xprt = NULL; | 541 | struct svc_xprt *xprt = NULL; |
533 | spin_lock_bh(&serv->sv_lock); | 542 | spin_lock_bh(&serv->sv_lock); |
534 | if (!list_empty(&serv->sv_tempsocks)) { | 543 | if (!list_empty(&serv->sv_tempsocks)) { |
535 | if (net_ratelimit()) { | 544 | if (net_ratelimit()) { |
536 | /* Try to help the admin */ | 545 | /* Try to help the admin */ |
537 | printk(KERN_NOTICE "%s: too many open " | 546 | printk(KERN_NOTICE "%s: too many open " |
538 | "connections, consider increasing the " | 547 | "connections, consider increasing %s\n", |
539 | "number of nfsd threads\n", | 548 | serv->sv_name, serv->sv_maxconn ? |
540 | serv->sv_name); | 549 | "the max number of connections." : |
550 | "the number of threads."); | ||
541 | } | 551 | } |
542 | /* | 552 | /* |
543 | * Always select the oldest connection. It's not fair, | 553 | * Always select the oldest connection. It's not fair, |