From b90e3102ae22c0d68582e20f73faec5c72f229eb Mon Sep 17 00:00:00 2001 From: yasuoka Date: Sat, 12 Jul 2014 21:06:34 +0000 Subject: [PATCH] Resize the pcb hashtable automatically. The table size will be doubled when the number of the hash entries reaches 75% of the table size. ok dlg henning, 'commit in' claudio --- sys/netinet/in_pcb.c | 44 +++++++++++++++++++++++++++++++++++++++- sys/netinet/in_pcb.h | 3 ++- sys/netinet/tcp_subr.c | 9 ++++---- sys/netinet/udp_usrreq.c | 9 ++++---- 4 files changed, 53 insertions(+), 12 deletions(-) diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 6bc1601b983..24305d94441 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in_pcb.c,v 1.156 2014/06/04 13:45:47 mpi Exp $ */ +/* $OpenBSD: in_pcb.c,v 1.157 2014/07/12 21:06:34 yasuoka Exp $ */ /* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */ /* @@ -118,6 +118,10 @@ struct baddynamicports baddynamicports; struct pool inpcb_pool; int inpcb_pool_initialized = 0; +int in_pcbresize (struct inpcbtable *, int); + +#define INPCBHASH_LOADFACTOR(_x) (((_x) * 3) / 4) + #define INPCBHASH(table, faddr, fport, laddr, lport, rdom) \ &(table)->inpt_hashtbl[(ntohl((faddr)->s_addr) + \ ntohs((fport)) + ntohs((lport)) + (rdom)) & (table->inpt_hash)] @@ -144,6 +148,7 @@ in_pcbinit(struct inpcbtable *table, int hashsize) if (table->inpt_lhashtbl == NULL) panic("in_pcbinit: hashinit failed for lport"); table->inpt_lastport = 0; + table->inpt_count = 0; } /* @@ -191,6 +196,9 @@ in_pcballoc(struct socket *so, struct inpcbtable *table) inp->inp_seclevel[SL_IPCOMP] = IPSEC_IPCOMP_LEVEL_DEFAULT; inp->inp_rtableid = curproc->p_p->ps_rtableid; s = splnet(); + if (table->inpt_hash != 0 && + table->inpt_count++ > INPCBHASH_LOADFACTOR(table->inpt_hash)) + (void)in_pcbresize(table, (table->inpt_hash + 1) * 2); TAILQ_INSERT_HEAD(&table->inpt_queue, inp, inp_queue); LIST_INSERT_HEAD(INPCBLHASH(table, inp->inp_lport, inp->inp_rtableid), inp, inp_lhash); @@ -502,6 +510,7 @@ in_pcbdetach(struct inpcb *inp) LIST_REMOVE(inp, inp_lhash); LIST_REMOVE(inp, inp_hash); TAILQ_REMOVE(&inp->inp_table->inpt_queue, inp, inp_queue); + inp->inp_table->inpt_count--; splx(s); pool_put(&inpcb_pool, inp); } @@ -880,6 +889,39 @@ in_pcbrehash(struct inpcb *inp) splx(s); } +int +in_pcbresize(struct inpcbtable *table, int hashsize) +{ + u_long nhash, nlhash; + void *nhashtbl, *nlhashtbl, *ohashtbl, *olhashtbl; + struct inpcb *inp0, *inp1; + + ohashtbl = table->inpt_hashtbl; + olhashtbl = table->inpt_lhashtbl; + + nhashtbl = hashinit(hashsize, M_PCB, M_NOWAIT, &nhash); + nlhashtbl = hashinit(hashsize, M_PCB, M_NOWAIT, &nlhash); + if (nhashtbl == NULL || nlhashtbl == NULL) { + if (nhashtbl != NULL) + free(nhashtbl, M_PCB, 0); + if (nlhashtbl != NULL) + free(nlhashtbl, M_PCB, 0); + return (ENOBUFS); + } + table->inpt_hashtbl = nhashtbl; + table->inpt_lhashtbl = nlhashtbl; + table->inpt_hash = nhash; + table->inpt_lhash = nlhash; + + TAILQ_FOREACH_SAFE(inp0, &table->inpt_queue, inp_queue, inp1) { + in_pcbrehash(inp0); + } + free(ohashtbl, M_PCB, 0); + free(olhashtbl, M_PCB, 0); + + return (0); +} + #ifdef DIAGNOSTIC int in_pcbnotifymiss = 0; #endif diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index 0c27f51c397..4923eac1a6a 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in_pcb.h,v 1.85 2014/04/18 10:48:29 jca Exp $ */ +/* $OpenBSD: in_pcb.h,v 1.86 2014/07/12 21:06:34 yasuoka Exp $ */ /* $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $ */ /* @@ -158,6 +158,7 @@ struct inpcbtable { LIST_HEAD(inpcbhead, inpcb) *inpt_hashtbl, *inpt_lhashtbl; u_long inpt_hash, inpt_lhash; u_int16_t inpt_lastport; + int inpt_count; }; /* flags in inp_flags: */ diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 74d8d7264c9..72ea22b354c 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_subr.c,v 1.130 2014/07/12 18:44:23 tedu Exp $ */ +/* $OpenBSD: tcp_subr.c,v 1.131 2014/07/12 21:06:34 yasuoka Exp $ */ /* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */ /* @@ -118,10 +118,9 @@ int tcp_do_rfc3390 = 2; /* Increase TCP's Initial Window to 10*mss */ u_int32_t tcp_now = 1; -#ifndef TCBHASHSIZE -#define TCBHASHSIZE 128 +#ifndef TCB_INITIAL_HASH_SIZE +#define TCB_INITIAL_HASH_SIZE 128 #endif -int tcbhashsize = TCBHASHSIZE; /* syn hash parameters */ #define TCP_SYN_HASH_SIZE 293 @@ -162,7 +161,7 @@ tcp_init() NULL); pool_sethardlimit(&sackhl_pool, tcp_sackhole_limit, NULL, 0); #endif /* TCP_SACK */ - in_pcbinit(&tcbtable, tcbhashsize); + in_pcbinit(&tcbtable, TCB_INITIAL_HASH_SIZE); #ifdef INET6 /* diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index e553b4ac5ce..162f7be93f1 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: udp_usrreq.c,v 1.187 2014/07/11 13:15:34 bluhm Exp $ */ +/* $OpenBSD: udp_usrreq.c,v 1.188 2014/07/12 21:06:34 yasuoka Exp $ */ /* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */ /* @@ -139,15 +139,14 @@ int udp_output(struct inpcb *, struct mbuf *, struct mbuf *, struct mbuf *); void udp_detach(struct inpcb *); void udp_notify(struct inpcb *, int); -#ifndef UDBHASHSIZE -#define UDBHASHSIZE 128 +#ifndef UDB_INITIAL_HASH_SIZE +#define UDB_INITIAL_HASH_SIZE 128 #endif -int udbhashsize = UDBHASHSIZE; void udp_init() { - in_pcbinit(&udbtable, udbhashsize); + in_pcbinit(&udbtable, UDB_INITIAL_HASH_SIZE); } #ifdef INET6 -- 2.20.1