Skip site navigation (1)Skip section navigation (2)
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>