Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 28 Jul 2026 21:20:53 +0000
From:      Richard Scheffenegger <rscheff@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 2d01998e9e8a - main - tcp_hostcache: ensure expire and prune values stay consistent with each other
Message-ID:  <6a691d35.1f3ce.1a72d9e5@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by rscheff:

URL: https://cgit.FreeBSD.org/src/commit/?id=2d01998e9e8ab3081d7f586d59dc41a487bb5f0c

commit 2d01998e9e8ab3081d7f586d59dc41a487bb5f0c
Author:     Richard Scheffenegger <rscheff@FreeBSD.org>
AuthorDate: 2026-07-28 20:42:25 +0000
Commit:     Richard Scheffenegger <rscheff@FreeBSD.org>
CommitDate: 2026-07-28 21:13:20 +0000

    tcp_hostcache: ensure expire and prune values stay consistent with each other
    
        When configuring the expire timeout to something short, make sure that the
        prune time runs at least at that interval. Similarly, when adjusting the
        prune interval up, ensure the expire timeout reflect that expected minimum
        time also. Finally, restart the callout timer so that the next pruning
        happens after the new, expected interval.
    
    Reviewed By:            glebius
    MFC after:              2 weeks
    Sponsored by:           NetApp, Inc.
    Differential Revision:  https://reviews.freebsd.org/D58424
---
 sys/netinet/tcp_hostcache.c | 64 +++++++++++++++++++++++++++++++++++++--------
 1 file changed, 53 insertions(+), 11 deletions(-)

diff --git a/sys/netinet/tcp_hostcache.c b/sys/netinet/tcp_hostcache.c
index 2ed035b6fd06..7a5e2ef095ec 100644
--- a/sys/netinet/tcp_hostcache.c
+++ b/sys/netinet/tcp_hostcache.c
@@ -128,9 +128,9 @@ struct tcp_hostcache {
 	u_int		bucket_limit;
 	u_int		cache_count;
 	u_int		cache_limit;
-	int		expire;
-	int		prune;
-	int		purgeall;
+	u_int		expire;
+	u_int		prune;
+	u_int		purgeall;
 };
 
 /* Arbitrary values */
@@ -146,6 +146,8 @@ VNET_DEFINE_STATIC(struct callout, tcp_hc_callout);
 #define	V_tcp_hc_callout	VNET(tcp_hc_callout)
 
 static struct hc_metrics *tcp_hc_lookup(const struct in_conninfo *);
+static int sysctl_tcp_hc_expire(SYSCTL_HANDLER_ARGS);
+static int sysctl_tcp_hc_prune(SYSCTL_HANDLER_ARGS);
 static int sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS);
 static int sysctl_tcp_hc_histo(SYSCTL_HANDLER_ARGS);
 static int sysctl_tcp_hc_purgenow(SYSCTL_HANDLER_ARGS);
@@ -178,15 +180,17 @@ SYSCTL_UINT(_net_inet_tcp_hostcache, OID_AUTO, count, CTLFLAG_VNET | CTLFLAG_RD,
     &VNET_NAME(tcp_hostcache.cache_count), 0,
     "Current number of entries in hostcache");
 
-SYSCTL_INT(_net_inet_tcp_hostcache, OID_AUTO, expire, CTLFLAG_VNET | CTLFLAG_RW,
-    &VNET_NAME(tcp_hostcache.expire), 0,
+SYSCTL_PROC(_net_inet_tcp_hostcache, OID_AUTO, expire,
+    CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE,
+    &VNET_NAME(tcp_hostcache.expire), 0, sysctl_tcp_hc_expire, "IU",
     "Expire time of TCP hostcache entries");
 
-SYSCTL_INT(_net_inet_tcp_hostcache, OID_AUTO, prune, CTLFLAG_VNET | CTLFLAG_RW,
-    &VNET_NAME(tcp_hostcache.prune), 0,
+SYSCTL_PROC(_net_inet_tcp_hostcache, OID_AUTO, prune,
+    CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE,
+    &VNET_NAME(tcp_hostcache.prune), 0, sysctl_tcp_hc_prune, "IU",
     "Time between purge runs");
 
-SYSCTL_INT(_net_inet_tcp_hostcache, OID_AUTO, purge, CTLFLAG_VNET | CTLFLAG_RW,
+SYSCTL_UINT(_net_inet_tcp_hostcache, OID_AUTO, purge, CTLFLAG_VNET | CTLFLAG_RW,
     &VNET_NAME(tcp_hostcache.purgeall), 0,
     "Expire all entries on next purge run");
 
@@ -201,8 +205,8 @@ SYSCTL_PROC(_net_inet_tcp_hostcache, OID_AUTO, histo,
     "Print a histogram of hostcache hashbucket utilization");
 
 SYSCTL_PROC(_net_inet_tcp_hostcache, OID_AUTO, purgenow,
-    CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
-    NULL, 0, sysctl_tcp_hc_purgenow, "I",
+    CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE,
+    NULL, 0, sysctl_tcp_hc_purgenow, "IU",
     "Immediately purge all entries");
 
 static MALLOC_DEFINE(M_HOSTCACHE, "hostcache", "TCP hostcache");
@@ -620,6 +624,44 @@ tcp_hc_update(const struct in_conninfo *inc, struct tcp_hc_metrics *hcm)
 	THC_UNLOCK(hc_head);
 }
 
+/*
+ * Sysctl function: adjusts the expire timeout and adjusts the prune value accordingly.
+ */
+static int
+sysctl_tcp_hc_expire(SYSCTL_HANDLER_ARGS)
+{
+	int error, expire;
+
+	expire = V_tcp_hostcache.expire;
+	error = sysctl_handle_int(oidp, &expire, 0, req);
+	if (error != 0 || !req->newptr)
+		return (error);
+	if (expire < V_tcp_hostcache.prune)
+		V_tcp_hostcache.prune = expire;
+	V_tcp_hostcache.expire = expire;
+	return (0);
+}
+
+/*
+ * Sysctl function: adjusts the prune time and adjusts the expire timeout accordingly.
+ */
+static int
+sysctl_tcp_hc_prune(SYSCTL_HANDLER_ARGS)
+{
+	int error, prune;
+
+	prune = V_tcp_hostcache.prune;
+	error = sysctl_handle_int(oidp, &prune, 0, req);
+	if (error != 0 || !req->newptr)
+		return (error);
+	if (prune > V_tcp_hostcache.expire)
+		V_tcp_hostcache.expire = prune;
+	V_tcp_hostcache.prune = prune;
+	callout_reset(&V_tcp_hc_callout, V_tcp_hostcache.prune * hz,
+	    tcp_hc_purge, curvnet);
+	return (0);
+}
+
 /*
  * Sysctl function: prints the list and values of all hostcache entries in
  * unsorted order.
@@ -831,7 +873,7 @@ sysctl_tcp_hc_purgenow(SYSCTL_HANDLER_ARGS)
 
 	val = 0;
 	error = sysctl_handle_int(oidp, &val, 0, req);
-	if (error || !req->newptr)
+	if (error != 0 || !req->newptr)
 		return (error);
 
 	if (val == 2)


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a691d35.1f3ce.1a72d9e5>