summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_socket.c
diff options
context:
space:
mode:
authorandre <andre@FreeBSD.org>2012-11-27 21:19:58 +0000
committerandre <andre@FreeBSD.org>2012-11-27 21:19:58 +0000
commitd85b5106083a0409d9363a626d353f7df04985ab (patch)
tree5dc983dac79a579c13f71506074ff18195e58a9f /sys/kern/uipc_socket.c
parentb436e47e367c9d1f318ae7add7279a2c84cdfdb7 (diff)
downloadFreeBSD-src-d85b5106083a0409d9363a626d353f7df04985ab.zip
FreeBSD-src-d85b5106083a0409d9363a626d353f7df04985ab.tar.gz
Base the mbuf related limits on the available physical memory or
kernel memory, whichever is lower. The overall mbuf related memory limit must be set so that mbufs (and clusters of various sizes) can't exhaust physical RAM or KVM. The limit is set to half of the physical RAM or KVM (whichever is lower) as the baseline. In any normal scenario we want to leave at least half of the physmem/kvm for other kernel functions and userspace to prevent it from swapping too easily. Via a tunable kern.maxmbufmem the limit can be upped to at most 3/4 of physmem/kvm. At the same time divorce maxfiles from maxusers and set maxfiles to physpages / 8 with a floor based on maxusers. This way busy servers can make use of the significantly increased mbuf limits with a much larger number of open sockets. Tidy up ordering in init_param2() and check up on some users of those values calculated here. Out of the overall mbuf memory limit 2K clusters and 4K (page size) clusters to get 1/4 each because these are the most heavily used mbuf sizes. 2K clusters are used for MTU 1500 ethernet inbound packets. 4K clusters are used whenever possible for sends on sockets and thus outbound packets. The larger cluster sizes of 9K and 16K are limited to 1/6 of the overall mbuf memory limit. When jumbo MTU's are used these large clusters will end up only on the inbound path. They are not used on outbound, there it's still 4K. Yes, that will stay that way because otherwise we run into lots of complications in the stack. And it really isn't a problem, so don't make a scene. Normal mbufs (256B) weren't limited at all previously. This was problematic as there are certain places in the kernel that on allocation failure of clusters try to piece together their packet from smaller mbufs. The mbuf limit is the number of all other mbuf sizes together plus some more to allow for standalone mbufs (ACK for example) and to send off a copy of a cluster. Unfortunately there isn't a way to set an overall limit for all mbuf memory together as UMA doesn't support such a limiting. NB: Every cluster also has an mbuf associated with it. Two examples on the revised mbuf sizing limits: 1GB KVM: 512MB limit for mbufs 419,430 mbufs 65,536 2K mbuf clusters 32,768 4K mbuf clusters 9,709 9K mbuf clusters 5,461 16K mbuf clusters 16GB RAM: 8GB limit for mbufs 33,554,432 mbufs 1,048,576 2K mbuf clusters 524,288 4K mbuf clusters 155,344 9K mbuf clusters 87,381 16K mbuf clusters These defaults should be sufficient for even the most demanding network loads. MFC after: 1 month
Diffstat (limited to 'sys/kern/uipc_socket.c')
-rw-r--r--sys/kern/uipc_socket.c9
1 files changed, 3 insertions, 6 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index e9ecd4e..7a2c792 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -290,7 +290,7 @@ init_maxsockets(void *ignored)
{
TUNABLE_INT_FETCH("kern.ipc.maxsockets", &maxsockets);
- maxsockets = imax(maxsockets, imax(maxfiles, nmbclusters));
+ maxsockets = imax(maxsockets, maxfiles);
}
SYSINIT(param, SI_SUB_TUNABLES, SI_ORDER_ANY, init_maxsockets, NULL);
@@ -306,12 +306,9 @@ sysctl_maxsockets(SYSCTL_HANDLER_ARGS)
newmaxsockets = maxsockets;
error = sysctl_handle_int(oidp, &newmaxsockets, 0, req);
if (error == 0 && req->newptr) {
- if (newmaxsockets > maxsockets) {
+ if (newmaxsockets > maxsockets &&
+ newmaxsockets <= maxfiles) {
maxsockets = newmaxsockets;
- if (maxsockets > ((maxfiles / 4) * 3)) {
- maxfiles = (maxsockets * 5) / 4;
- maxfilesperproc = (maxfiles * 9) / 10;
- }
EVENTHANDLER_INVOKE(maxsockets_change);
} else
error = EINVAL;
OpenPOWER on IntegriCloud