The branch main has been updated by rscheff:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=95e56d31e348594973affd0ea81d8f8383bc3031

commit 95e56d31e348594973affd0ea81d8f8383bc3031
Author:     Richard Scheffenegger <[email protected]>
AuthorDate: 2021-03-31 17:30:20 +0000
Commit:     Richard Scheffenegger <[email protected]>
CommitDate: 2021-03-31 18:24:13 +0000

    tcp: Make hostcache.cache_count MPSAFE  by using a counter_u64_t
    
    Addressing the underlying root cause for cache_count to
    show unexpectedly high  values, by protecting all arithmetic on
    that global variable by using counter(9).
    
    PR:             254333
    Reviewed By: tuexen, #transport
    MFC after: 2 weeks
    Sponsored by: NetApp, Inc.
    Differential Revision: https://reviews.freebsd.org/D29510
---
 sys/netinet/tcp_hostcache.c | 20 ++++++++++++--------
 sys/netinet/tcp_hostcache.h | 20 ++++++++++----------
 2 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/sys/netinet/tcp_hostcache.c b/sys/netinet/tcp_hostcache.c
index b6d0c0410df9..67da97405c3f 100644
--- a/sys/netinet/tcp_hostcache.c
+++ b/sys/netinet/tcp_hostcache.c
@@ -147,8 +147,8 @@ SYSCTL_UINT(_net_inet_tcp_hostcache, OID_AUTO, bucketlimit,
     CTLFLAG_VNET | CTLFLAG_RDTUN, &VNET_NAME(tcp_hostcache.bucket_limit), 0,
     "Per-bucket hash limit for hostcache");
 
-SYSCTL_UINT(_net_inet_tcp_hostcache, OID_AUTO, count, CTLFLAG_VNET | 
CTLFLAG_RD,
-     &VNET_NAME(tcp_hostcache.cache_count), 0,
+SYSCTL_COUNTER_U64(_net_inet_tcp_hostcache, OID_AUTO, count, CTLFLAG_VNET | 
CTLFLAG_RD,
+     &VNET_NAME(tcp_hostcache.cache_count),
     "Current number of entries in hostcache");
 
 SYSCTL_INT(_net_inet_tcp_hostcache, OID_AUTO, expire, CTLFLAG_VNET | 
CTLFLAG_RW,
@@ -199,7 +199,8 @@ tcp_hc_init(void)
        /*
         * Initialize hostcache structures.
         */
-       V_tcp_hostcache.cache_count = 0;
+       V_tcp_hostcache.cache_count = counter_u64_alloc(M_WAITOK);
+       counter_u64_zero(V_tcp_hostcache.cache_count);
        V_tcp_hostcache.hashsize = TCP_HOSTCACHE_HASHSIZE;
        V_tcp_hostcache.bucket_limit = TCP_HOSTCACHE_BUCKETLIMIT;
        V_tcp_hostcache.expire = TCP_HOSTCACHE_EXPIRE;
@@ -267,6 +268,9 @@ tcp_hc_destroy(void)
        /* Purge all hc entries. */
        tcp_hc_purge_internal(1);
 
+       /* Release the counter */
+       counter_u64_free(V_tcp_hostcache.cache_count);
+
        /* Free the uma zone and the allocated hash table. */
        uma_zdestroy(V_tcp_hostcache.zone);
 
@@ -374,7 +378,7 @@ tcp_hc_insert(struct in_conninfo *inc)
         * If the bucket limit is reached, reuse the least-used element.
         */
        if (hc_head->hch_length >= V_tcp_hostcache.bucket_limit ||
-           V_tcp_hostcache.cache_count >= V_tcp_hostcache.cache_limit) {
+           counter_u64_fetch(V_tcp_hostcache.cache_count) >= 
V_tcp_hostcache.cache_limit) {
                hc_entry = TAILQ_LAST(&hc_head->hch_bucket, hc_qhead);
                /*
                 * At first we were dropping the last element, just to
@@ -391,7 +395,7 @@ tcp_hc_insert(struct in_conninfo *inc)
                }
                TAILQ_REMOVE(&hc_head->hch_bucket, hc_entry, rmx_q);
                V_tcp_hostcache.hashbase[hash].hch_length--;
-               V_tcp_hostcache.cache_count--;
+               counter_u64_add(V_tcp_hostcache.cache_count, -1);
                TCPSTAT_INC(tcps_hc_bucketoverflow);
 #if 0
                uma_zfree(V_tcp_hostcache.zone, hc_entry);
@@ -424,7 +428,7 @@ tcp_hc_insert(struct in_conninfo *inc)
         */
        TAILQ_INSERT_HEAD(&hc_head->hch_bucket, hc_entry, rmx_q);
        V_tcp_hostcache.hashbase[hash].hch_length++;
-       V_tcp_hostcache.cache_count++;
+       counter_u64_add(V_tcp_hostcache.cache_count, 1);
        TCPSTAT_INC(tcps_hc_added);
 
        return hc_entry;
@@ -640,7 +644,7 @@ sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS)
 
        /* Optimize Buffer length query by sbin/sysctl */
        if (req->oldptr == NULL) {
-               len = (V_tcp_hostcache.cache_count + 1) * linesize;
+               len = (counter_u64_fetch(V_tcp_hostcache.cache_count) + 1) * 
linesize;
                return (SYSCTL_OUT(req, NULL, len));
        }
 
@@ -712,7 +716,7 @@ tcp_hc_purge_internal(int all)
                                              hc_entry, rmx_q);
                                uma_zfree(V_tcp_hostcache.zone, hc_entry);
                                V_tcp_hostcache.hashbase[i].hch_length--;
-                               V_tcp_hostcache.cache_count--;
+                               counter_u64_add(V_tcp_hostcache.cache_count, 
-1);
                        } else
                                hc_entry->rmx_expire -= V_tcp_hostcache.prune;
                }
diff --git a/sys/netinet/tcp_hostcache.h b/sys/netinet/tcp_hostcache.h
index f4e1013aac60..b5237392acc2 100644
--- a/sys/netinet/tcp_hostcache.h
+++ b/sys/netinet/tcp_hostcache.h
@@ -69,16 +69,16 @@ struct hc_metrics {
 };
 
 struct tcp_hostcache {
-       struct  hc_head *hashbase;
-       uma_zone_t zone;
-       u_int   hashsize;
-       u_int   hashmask;
-       u_int   bucket_limit;
-       u_int   cache_count;
-       u_int   cache_limit;
-       int     expire;
-       int     prune;
-       int     purgeall;
+       struct hc_head  *hashbase;
+       uma_zone_t      zone;
+       u_int           hashsize;
+       u_int           hashmask;
+       u_int           bucket_limit;
+       counter_u64_t   cache_count;
+       u_int           cache_limit;
+       int             expire;
+       int             prune;
+       int             purgeall;
 };
 
 #endif /* !_NETINET_TCP_HOSTCACHE_H_*/
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to