Date: Wed, 29 Apr 2026 16:19:35 +0000 From: Gleb Smirnoff <glebius@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 6883b120c537 - main - inpcb: allow to specify different sizes for port and load balance hashes Message-ID: <69f22f97.1f0b5.133b0f3b@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=6883b120c53735ff1681ef96d257f376731f56b3 commit 6883b120c53735ff1681ef96d257f376731f56b3 Author: Gleb Smirnoff <glebius@FreeBSD.org> AuthorDate: 2026-04-29 16:19:14 +0000 Commit: Gleb Smirnoff <glebius@FreeBSD.org> CommitDate: 2026-04-29 16:19:14 +0000 inpcb: allow to specify different sizes for port and load balance hashes Understand zero size as instruction to not allocate the hash. Do not allocate both hashes for rawip(4). There are no functional changes to TCP or UDP. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D56705 --- sys/netinet/in_pcb.c | 37 +++++++++++++++++++++++++------------ sys/netinet/in_pcb.h | 5 +++-- sys/netinet/raw_ip.c | 2 +- sys/netinet/tcp_subr.c | 2 +- sys/netinet/udp_usrreq.c | 5 +++-- 5 files changed, 33 insertions(+), 18 deletions(-) diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 2e1a00209cb4..66d2c610139f 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -302,7 +302,7 @@ in_pcblbgroup_find(struct inpcb *inp) INP_HASH_LOCK_ASSERT(pcbinfo); hdr = &pcbinfo->ipi_lbgrouphashbase[ - INP_PCBPORTHASH(inp->inp_lport, pcbinfo->ipi_porthashmask)]; + INP_PCBPORTHASH(inp->inp_lport, pcbinfo->ipi_lbgrouphashmask)]; CK_LIST_FOREACH(grp, hdr, il_list) { struct inpcb *inp1; @@ -410,7 +410,7 @@ in_pcbinslbgrouphash(struct inpcb *inp, uint8_t numa_domain) } #endif - idx = INP_PCBPORTHASH(inp->inp_lport, pcbinfo->ipi_porthashmask); + idx = INP_PCBPORTHASH(inp->inp_lport, pcbinfo->ipi_lbgrouphashmask); hdr = &pcbinfo->ipi_lbgrouphashbase[idx]; CK_LIST_FOREACH(grp, hdr, il_list) { if (grp->il_cred->cr_prison == inp->inp_cred->cr_prison && @@ -471,7 +471,7 @@ in_pcbremlbgrouphash(struct inpcb *inp) INP_HASH_WLOCK_ASSERT(pcbinfo); hdr = &pcbinfo->ipi_lbgrouphashbase[ - INP_PCBPORTHASH(inp->inp_lport, pcbinfo->ipi_porthashmask)]; + INP_PCBPORTHASH(inp->inp_lport, pcbinfo->ipi_lbgrouphashmask)]; CK_LIST_FOREACH(grp, hdr, il_list) { for (i = 0; i < grp->il_inpcnt; ++i) { if (grp->il_inp[i] != inp) @@ -547,7 +547,7 @@ in_pcblbgroup_numa(struct inpcb *inp, int arg) */ void in_pcbinfo_init(struct inpcbinfo *pcbinfo, struct inpcbstorage *pcbstor, - u_int hash_nelements, u_int porthash_nelements) + u_int hash_nelements, u_int porthash_nelements, u_int lbgrouphash_nelements) { struct hashalloc_args ha = { .mtype = M_PCB, @@ -565,10 +565,18 @@ in_pcbinfo_init(struct inpcbinfo *pcbinfo, struct inpcbstorage *pcbstor, pcbinfo->ipi_hash_wild = hashalloc(&ha); pcbinfo->ipi_hashmask = ha.size - 1; - ha.size = imin(porthash_nelements, IPPORT_MAX + 1); - pcbinfo->ipi_porthashbase = hashalloc(&ha); - pcbinfo->ipi_lbgrouphashbase = hashalloc(&ha); - pcbinfo->ipi_porthashmask = ha.size - 1; + if (porthash_nelements > 0) { + ha.size = imin(porthash_nelements, IPPORT_MAX + 1); + pcbinfo->ipi_porthashbase = hashalloc(&ha); + pcbinfo->ipi_porthashmask = ha.size - 1; + } else + pcbinfo->ipi_porthashbase = NULL; + if (lbgrouphash_nelements > 0) { + ha.size = imin(lbgrouphash_nelements, IPPORT_MAX + 1); + pcbinfo->ipi_lbgrouphashbase = hashalloc(&ha); + pcbinfo->ipi_lbgrouphashmask = ha.size - 1; + } else + pcbinfo->ipi_lbgrouphashbase = NULL; pcbinfo->ipi_zone = pcbstor->ips_zone; pcbinfo->ipi_smr = uma_zone_get_smr(pcbinfo->ipi_zone); @@ -591,9 +599,14 @@ in_pcbinfo_destroy(struct inpcbinfo *pcbinfo) ha.size = pcbinfo->ipi_hashmask + 1; hashfree(pcbinfo->ipi_hash_exact, &ha); hashfree(pcbinfo->ipi_hash_wild, &ha); - ha.size = pcbinfo->ipi_porthashmask + 1; - hashfree(pcbinfo->ipi_porthashbase, &ha); - hashfree(pcbinfo->ipi_lbgrouphashbase, &ha); + if (pcbinfo->ipi_porthashbase != NULL) { + ha.size = pcbinfo->ipi_porthashmask + 1; + hashfree(pcbinfo->ipi_porthashbase, &ha); + } + if (pcbinfo->ipi_lbgrouphashbase != NULL) { + ha.size = pcbinfo->ipi_lbgrouphashmask + 1; + hashfree(pcbinfo->ipi_lbgrouphashbase, &ha); + } mtx_destroy(&pcbinfo->ipi_hash_lock); } @@ -2154,7 +2167,7 @@ in_pcblookup_lbgroup(const struct inpcbinfo *pcbinfo, NET_EPOCH_ASSERT(); hdr = &pcbinfo->ipi_lbgrouphashbase[ - INP_PCBPORTHASH(lport, pcbinfo->ipi_porthashmask)]; + INP_PCBPORTHASH(lport, pcbinfo->ipi_lbgrouphashmask)]; /* * Search for an LB group match based on the following criteria: diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index fb52f59ff725..ea93780730de 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -463,7 +463,8 @@ struct inpcbinfo { struct inpcbhead *ipi_hash_exact; /* (r:e/w:h) */ struct inpcbhead *ipi_hash_wild; /* (r:e/w:h) */ u_long ipi_hashmask; /* (c) */ - u_long ipi_porthashmask; /* (h) */ + u_long ipi_porthashmask; /* (c) */ + u_long ipi_lbgrouphashmask; /* (c) */ /* * Global hash of inpcbs, hashed by only local port number. @@ -644,7 +645,7 @@ VNET_DECLARE(int, ipport_randomized); #define V_ipport_randomized VNET(ipport_randomized) void in_pcbinfo_init(struct inpcbinfo *, struct inpcbstorage *, - u_int, u_int); + u_int, u_int, u_int); void in_pcbinfo_destroy(struct inpcbinfo *); void in_pcbstorage_init(void *); void in_pcbstorage_destroy(void *); diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index 6f2b4dd9cb05..48e20df3ef9a 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -147,7 +147,7 @@ static void rip_init(void *arg __unused) { #define INP_PCBHASH_RAW_SIZE 256 - in_pcbinfo_init(&V_ripcbinfo, &ripcbstor, INP_PCBHASH_RAW_SIZE, 1); + in_pcbinfo_init(&V_ripcbinfo, &ripcbstor, INP_PCBHASH_RAW_SIZE, 0, 0); } VNET_SYSINIT(rip_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, rip_init, NULL); diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 9844ba176237..2b7ac6c4701d 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -1454,7 +1454,7 @@ tcp_vnet_init(void *arg __unused) __func__); #endif in_pcbinfo_init(&V_tcbinfo, &tcpcbstor, tcp_tcbhashsize, - tcp_tcbhashsize); + tcp_tcbhashsize, tcp_tcbhashsize); syncache_init(); tcp_hc_init(); diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 23b0ca684b09..22faf1cc1ec9 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -180,10 +180,11 @@ udp_vnet_init(void *arg __unused) * Once we can calculate the flowid that way and re-establish * a 4-tuple, flip this to 4-tuple. */ - in_pcbinfo_init(&V_udbinfo, &udpcbstor, UDBHASHSIZE, UDBHASHSIZE); + in_pcbinfo_init(&V_udbinfo, &udpcbstor, UDBHASHSIZE, UDBHASHSIZE, + UDBHASHSIZE); /* Additional pcbinfo for UDP-Lite */ in_pcbinfo_init(&V_ulitecbinfo, &udplitecbstor, UDBHASHSIZE, - UDBHASHSIZE); + UDBHASHSIZE, UDBHASHSIZE); } VNET_SYSINIT(udp_vnet_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, udp_vnet_init, NULL);home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69f22f97.1f0b5.133b0f3b>
