X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/593a1d5fd87cdf5b46dd5fcb84467b432cea0f91..4bd07ac2140668789aa3ee8ec4dde4a3e0a3bba5:/bsd/dev/unix_startup.c?ds=sidebyside diff --git a/bsd/dev/unix_startup.c b/bsd/dev/unix_startup.c index d2dd20b11..25c3610d0 100644 --- a/bsd/dev/unix_startup.c +++ b/bsd/dev/unix_startup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2014 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -39,25 +39,34 @@ #include #include +#include +#include #include +#include #include #include #include #include #include -#include +#include +#include +#include +#include +#include +extern uint32_t kern_maxvnodes; extern vm_map_t mb_map; #if INET || INET6 -extern u_long tcp_sendspace; -extern u_long tcp_recvspace; +extern uint32_t tcp_sendspace; +extern uint32_t tcp_recvspace; #endif -void bsd_bufferinit(void) __attribute__((section("__TEXT, initcode"))); -extern void md_prepare_for_shutdown(int, int, char *); +void bsd_bufferinit(void); -int bsd_mbuf_cluster_reserve(void); +unsigned int bsd_mbuf_cluster_reserve(boolean_t *); +void bsd_scale_setup(int); +void bsd_exec_setup(int); /* * Declare these as initialized data so we can patch them. @@ -65,7 +74,7 @@ int bsd_mbuf_cluster_reserve(void); #ifdef NBUF int max_nbuf_headers = NBUF; -int niobuf_headers = NBUF / 2; +int niobuf_headers = (NBUF / 2) + 2048; int nbuf_hashelements = NBUF; int nbuf_headers = NBUF; #else @@ -75,18 +84,22 @@ int nbuf_hashelements = 0; int nbuf_headers = 0; #endif -SYSCTL_INT (_kern, OID_AUTO, nbuf, CTLFLAG_RD, &nbuf_headers, 0, ""); -SYSCTL_INT (_kern, OID_AUTO, maxnbuf, CTLFLAG_RW, &max_nbuf_headers, 0, ""); +SYSCTL_INT (_kern, OID_AUTO, nbuf, CTLFLAG_RD | CTLFLAG_LOCKED, &nbuf_headers, 0, ""); +SYSCTL_INT (_kern, OID_AUTO, maxnbuf, CTLFLAG_RW | CTLFLAG_LOCKED, &max_nbuf_headers, 0, ""); __private_extern__ int customnbuf = 0; -int srv = 0; /* Flag indicates a server boot when set */ +int serverperfmode = 0; /* Flag indicates a server boot when set */ int ncl = 0; +#if SOCKETS +static unsigned int mbuf_poolsz; +#endif + vm_map_t buffer_map; vm_map_t bufferhdr_map; +static int vnodes_sized = 0; - -extern void bsd_startupearly(void) __attribute__((section("__TEXT, initcode"))); +extern void bsd_startupearly(void); void bsd_startupearly(void) @@ -97,7 +110,7 @@ bsd_startupearly(void) /* clip the number of buf headers upto 16k */ if (max_nbuf_headers == 0) - max_nbuf_headers = atop(sane_size / 50); /* Get 2% of ram, but no more than we can map */ + max_nbuf_headers = atop_kernel(sane_size / 50); /* Get 2% of ram, but no more than we can map */ if ((customnbuf == 0) && (max_nbuf_headers > 16384)) max_nbuf_headers = 16384; if (max_nbuf_headers < CONFIG_MIN_NBUF) @@ -105,16 +118,18 @@ bsd_startupearly(void) /* clip the number of hash elements to 200000 */ if ( (customnbuf == 0 ) && nbuf_hashelements == 0) { - nbuf_hashelements = atop(sane_size / 50); + nbuf_hashelements = atop_kernel(sane_size / 50); if (nbuf_hashelements > 200000) nbuf_hashelements = 200000; } else nbuf_hashelements = max_nbuf_headers; - if (niobuf_headers == 0) - niobuf_headers = max_nbuf_headers; - if (niobuf_headers > 4096) - niobuf_headers = 4096; + if (niobuf_headers == 0) { + if (max_nbuf_headers < 4096) + niobuf_headers = max_nbuf_headers; + else + niobuf_headers = (max_nbuf_headers / 2) + 2048; + } if (niobuf_headers < CONFIG_MIN_NIOBUF) niobuf_headers = CONFIG_MIN_NIOBUF; @@ -125,7 +140,7 @@ bsd_startupearly(void) &firstaddr, size, FALSE, - VM_FLAGS_ANYWHERE, + VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_KERN_MEMORY_FILE), &bufferhdr_map); if (ret != KERN_SUCCESS) @@ -135,7 +150,8 @@ bsd_startupearly(void) &firstaddr, size, 0, - KMA_HERE | KMA_KOBJECT); + KMA_HERE | KMA_KOBJECT, + VM_KERN_MEMORY_FILE); if (ret != KERN_SUCCESS) panic("Failed to allocate bufferhdr_map"); @@ -145,14 +161,10 @@ bsd_startupearly(void) #if SOCKETS { -#if CONFIG_USESOCKTHRESHOLD - static const unsigned int maxspace = 64 * 1024; -#else static const unsigned int maxspace = 128 * 1024; -#endif int scale; - nmbclusters = bsd_mbuf_cluster_reserve() / MCLBYTES; + nmbclusters = bsd_mbuf_cluster_reserve(NULL) / MCLBYTES; #if INET || INET6 if ((scale = nmbclusters / NMBCLUSTERS) > 1) { @@ -168,35 +180,46 @@ bsd_startupearly(void) } #endif /* SOCKETS */ - /* - * Size vnodes based on memory - * Number vnodes is (memsize/64k) + 1024 - * This is the calculation that is used by launchd in tiger - * we are clipping the max based on 16G - * ie ((16*1024*1024*1024)/(64 *1024)) + 1024 = 263168; - * CONFIG_VNODES is set to 263168 for "medium" configurations (the default) - * but can be smaller or larger. - */ - desiredvnodes = (sane_size/65536) + 1024; - if (desiredvnodes > CONFIG_VNODES) - desiredvnodes = CONFIG_VNODES; + if (vnodes_sized == 0) { + if (!PE_get_default("kern.maxvnodes", &desiredvnodes, sizeof(desiredvnodes))) { + /* + * Size vnodes based on memory + * Number vnodes is (memsize/64k) + 1024 + * This is the calculation that is used by launchd in tiger + * we are clipping the max based on 16G + * ie ((16*1024*1024*1024)/(64 *1024)) + 1024 = 263168; + * CONFIG_VNODES is set to 263168 for "medium" configurations (the default) + * but can be smaller or larger. + */ + desiredvnodes = (sane_size/65536) + 1024; +#ifdef CONFIG_VNODES + if (desiredvnodes > CONFIG_VNODES) + desiredvnodes = CONFIG_VNODES; +#endif + } + vnodes_sized = 1; + } } void bsd_bufferinit(void) { +#if SOCKETS kern_return_t ret; - - cons.t_dev = makedev(12, 0); +#endif + /* + * Note: Console device initialized in kminit() from bsd_autoconf() + * prior to call to us in bsd_init(). + */ bsd_startupearly(); #if SOCKETS ret = kmem_suballoc(kernel_map, - (vm_offset_t *) & mbutl, + (vm_offset_t *) &mbutl, (vm_size_t) (nmbclusters * MCLBYTES), FALSE, - VM_FLAGS_ANYWHERE, + VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_KERN_MEMORY_MBUF), &mb_map); if (ret != KERN_SUCCESS) @@ -209,7 +232,15 @@ bsd_bufferinit(void) bufinit(); } +/* 512 MB (K32) or 2 GB (K64) hard limit on size of the mbuf pool */ +#if !defined(__LP64__) +#define MAX_MBUF_POOL (512 << MBSHIFT) +#else +#define MAX_MBUF_POOL (2ULL << GBSHIFT) +#endif /* !__LP64__ */ +#define MAX_NCL (MAX_MBUF_POOL >> MCLSHIFT) +#if SOCKETS /* * this has been broken out into a separate routine that * can be called from the x86 early vm initialization to @@ -217,19 +248,109 @@ bsd_bufferinit(void) * DMA hardware that can't fully address all of the physical * memory that is present. */ -int -bsd_mbuf_cluster_reserve(void) +unsigned int +bsd_mbuf_cluster_reserve(boolean_t *overridden) { - if (sane_size > (64 * 1024 * 1024) || ncl) { + int mbuf_pool = 0; + static boolean_t was_overridden = FALSE; + + /* If called more than once, return the previously calculated size */ + if (mbuf_poolsz != 0) + goto done; + + /* + * Some of these are parsed in parse_bsd_args(), but for x86 we get + * here early from i386_vm_init() and so we parse them now, in order + * to correctly compute the size of the low-memory VM pool. It is + * redundant but rather harmless. + */ + (void) PE_parse_boot_argn("ncl", &ncl, sizeof (ncl)); + (void) PE_parse_boot_argn("mbuf_pool", &mbuf_pool, sizeof (mbuf_pool)); + + /* + * Convert "mbuf_pool" from MB to # of 2KB clusters; it is + * equivalent to "ncl", except that it uses different unit. + */ + if (mbuf_pool != 0) + ncl = (mbuf_pool << MBSHIFT) >> MCLSHIFT; + + if (sane_size > (64 * 1024 * 1024) || ncl != 0) { + + if (ncl || serverperfmode) + was_overridden = TRUE; if ((nmbclusters = ncl) == 0) { - if ((nmbclusters = ((sane_size / 16)/MCLBYTES)) > 32768) - nmbclusters = 32768; + /* Auto-configure the mbuf pool size */ + nmbclusters = mbuf_default_ncl(serverperfmode, sane_size); + } else { + /* Make sure it's not odd in case ncl is manually set */ + if (nmbclusters & 0x1) + --nmbclusters; + + /* And obey the upper limit */ + if (nmbclusters > MAX_NCL) + nmbclusters = MAX_NCL; } - /* Make sure it's not odd in case ncl is manually set */ - if (nmbclusters & 0x1) - --nmbclusters; + + /* Round it down to nearest multiple of PAGE_SIZE */ + nmbclusters = P2ROUNDDOWN(nmbclusters, NCLPG); } + mbuf_poolsz = nmbclusters << MCLSHIFT; +done: + if (overridden) + *overridden = was_overridden; + + return (mbuf_poolsz); +} +#endif + +#if defined(__LP64__) +extern int tcp_tcbhashsize; +extern int max_cached_sock_count; +#endif + - return (nmbclusters * MCLBYTES); +void +bsd_scale_setup(int scale) +{ +#if defined(__LP64__) + if ((scale > 0) && (serverperfmode == 0)) { + maxproc *= scale; + maxprocperuid = (maxproc * 2) / 3; + } + /* Apply server scaling rules */ + if ((scale > 0) && (serverperfmode !=0)) { + maxproc = 2500 * scale; + hard_maxproc = maxproc; + /* no fp usage */ + maxprocperuid = (maxproc*3)/4; + maxfiles = (150000 * scale); + maxfilesperproc = maxfiles/2; + desiredvnodes = maxfiles; + vnodes_sized = 1; + tcp_tfo_backlog = 100 * scale; + if (scale > 4) { + /* clip somaxconn at 32G level */ + somaxconn = 2048; + /* + * For scale > 4 (> 32G), clip + * tcp_tcbhashsize to 32K + */ + tcp_tcbhashsize = 32 *1024; + + if (scale > 7) { + /* clip at 64G level */ + max_cached_sock_count = 165000; + } else { + max_cached_sock_count = 60000 + ((scale-1) * 15000); + } + } else { + somaxconn = 512*scale; + tcp_tcbhashsize = 4*1024*scale; + max_cached_sock_count = 60000 + ((scale-1) * 15000); + } + } +#endif + bsd_exec_setup(scale); } +