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.
This commit is contained in:
parent
518d1f1f8f
commit
4d556cc343
@ -235,7 +235,7 @@ static char * tcp_log_addr(struct in_conninfo *inc, struct tcphdr *th,
|
|||||||
* variable net.inet.tcp.tcbhashsize
|
* variable net.inet.tcp.tcbhashsize
|
||||||
*/
|
*/
|
||||||
#ifndef TCBHASHSIZE
|
#ifndef TCBHASHSIZE
|
||||||
#define TCBHASHSIZE 512
|
#define TCBHASHSIZE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -282,11 +282,35 @@ tcp_inpcb_init(void *mem, int size, int flags)
|
|||||||
return (0);
|
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
|
void
|
||||||
tcp_init(void)
|
tcp_init(void)
|
||||||
{
|
{
|
||||||
|
const char *tcbhash_tuneable;
|
||||||
int hashsize;
|
int hashsize;
|
||||||
|
|
||||||
|
tcbhash_tuneable = "net.inet.tcp.tcbhashsize";
|
||||||
|
|
||||||
if (hhook_head_register(HHOOK_TYPE_TCP, HHOOK_TCP_EST_IN,
|
if (hhook_head_register(HHOOK_TYPE_TCP, HHOOK_TCP_EST_IN,
|
||||||
&V_tcp_hhh[HHOOK_TCP_EST_IN], HHOOK_NOWAIT|HHOOK_HEADISINVNET) != 0)
|
&V_tcp_hhh[HHOOK_TCP_EST_IN], HHOOK_NOWAIT|HHOOK_HEADISINVNET) != 0)
|
||||||
printf("%s: WARNING: unable to register helper hook\n", __func__);
|
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__);
|
printf("%s: WARNING: unable to register helper hook\n", __func__);
|
||||||
|
|
||||||
hashsize = TCBHASHSIZE;
|
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)) {
|
if (!powerof2(hashsize)) {
|
||||||
printf("WARNING: TCB hash size not a power of 2\n");
|
int oldhashsize = hashsize;
|
||||||
hashsize = 512; /* safe default */
|
|
||||||
|
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,
|
in_pcbinfo_init(&V_tcbinfo, "tcp", &V_tcb, hashsize, hashsize,
|
||||||
"tcp_inpcb", tcp_inpcb_init, NULL, UMA_ZONE_NOFREE,
|
"tcp_inpcb", tcp_inpcb_init, NULL, UMA_ZONE_NOFREE,
|
||||||
|
Loading…
Reference in New Issue
Block a user