summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2014-07-12 21:06:35 +0000
committerYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2014-07-12 21:06:35 +0000
commitec568b6cf9ff3e20820b23977efcf8464322bafa (patch)
treeb64fac2962cbc4495603ee7883d4cefa4ddcf560 /sys
parenta9810777b8982f665ef03499c7420769ba79251a (diff)
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
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/in_pcb.c44
-rw-r--r--sys/netinet/in_pcb.h3
-rw-r--r--sys/netinet/tcp_subr.c9
-rw-r--r--sys/netinet/udp_usrreq.c9
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