From owner-svn-src-head@FreeBSD.ORG Tue Nov 27 03:04:25 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 540E3CF1; Tue, 27 Nov 2012 03:04:25 +0000 (UTC) (envelope-from alfred@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 39A768FC08; Tue, 27 Nov 2012 03:04:25 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id qAR34PtI056692; Tue, 27 Nov 2012 03:04:25 GMT (envelope-from alfred@svn.freebsd.org) Received: (from alfred@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id qAR34PfD056691; Tue, 27 Nov 2012 03:04:25 GMT (envelope-from alfred@svn.freebsd.org) Message-Id: <201211270304.qAR34PfD056691@svn.freebsd.org> From: Alfred Perlstein Date: Tue, 27 Nov 2012 03:04:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r243594 - head/sys/netinet X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Nov 2012 03:04:25 -0000 Author: alfred Date: Tue Nov 27 03:04:24 2012 New Revision: 243594 URL: http://svnweb.freebsd.org/changeset/base/243594 Log: Auto size the tcbhashsize structure based on max sockets. While here, also make the code that enforces power-of-two more forgiving, instead of just resetting to 512, graciously round-down to the next lower power of two. Modified: head/sys/netinet/tcp_subr.c Modified: head/sys/netinet/tcp_subr.c ============================================================================== --- head/sys/netinet/tcp_subr.c Tue Nov 27 02:28:42 2012 (r243593) +++ head/sys/netinet/tcp_subr.c Tue Nov 27 03:04:24 2012 (r243594) @@ -235,7 +235,7 @@ static char * tcp_log_addr(struct in_con * variable net.inet.tcp.tcbhashsize */ #ifndef TCBHASHSIZE -#define TCBHASHSIZE 512 +#define TCBHASHSIZE 0 #endif /* @@ -282,11 +282,35 @@ tcp_inpcb_init(void *mem, int size, int return (0); } +/* + * Take a value and get the next power of 2 that doesn't overflow. + * Used to size the tcp_inpcb hash buckets. + */ +static int +maketcp_hashsize(int size) +{ + int hashsize; + + /* + * auto tune. + * get the next power of 2 higher than maxsockets. + */ + hashsize = 1 << fls(size); + /* catch overflow, and just go one power of 2 smaller */ + if (hashsize < size) { + hashsize = 1 << (fls(size) - 1); + } + return (hashsize); +} + void tcp_init(void) { + const char *tcbhash_tuneable; int hashsize; + tcbhash_tuneable = "net.inet.tcp.tcbhashsize"; + if (hhook_head_register(HHOOK_TYPE_TCP, HHOOK_TCP_EST_IN, &V_tcp_hhh[HHOOK_TCP_EST_IN], HHOOK_NOWAIT|HHOOK_HEADISINVNET) != 0) printf("%s: WARNING: unable to register helper hook\n", __func__); @@ -295,10 +319,43 @@ tcp_init(void) printf("%s: WARNING: unable to register helper hook\n", __func__); hashsize = TCBHASHSIZE; - TUNABLE_INT_FETCH("net.inet.tcp.tcbhashsize", &hashsize); + TUNABLE_INT_FETCH(tcbhash_tuneable, &hashsize); + if (hashsize == 0) { + /* + * Auto tune the hash size based on maxsockets. + * A perfect hash would have a 1:1 mapping + * (hashsize = maxsockets) however it's been + * suggested that O(2) average is better. + */ + hashsize = maketcp_hashsize(maxsockets / 4); + /* + * Our historical default is 512, + * do not autotune lower than this. + */ + if (hashsize < 512) + hashsize = 512; + if (bootverbose) + printf("%s: %s auto tuned to %d\n", __func__, + tcbhash_tuneable, hashsize); + } + /* + * We require a hashsize to be a power of two. + * Previously if it was not a power of two we would just reset it + * back to 512, which could be a nasty surprise if you did not notice + * the error message. + * Instead what we do is clip it to the closest power of two lower + * than the specified hash value. + */ if (!powerof2(hashsize)) { - printf("WARNING: TCB hash size not a power of 2\n"); - hashsize = 512; /* safe default */ + int oldhashsize = hashsize; + + hashsize = maketcp_hashsize(hashsize); + /* prevent absurdly low value */ + if (hashsize < 16) + hashsize = 16; + printf("%s: WARNING: TCB hash size not a power of 2, " + "clipped from %d to %d.\n", __func__, oldhashsize, + hashsize); } in_pcbinfo_init(&V_tcbinfo, "tcp", &V_tcb, hashsize, hashsize, "tcp_inpcb", tcp_inpcb_init, NULL, UMA_ZONE_NOFREE,