Date: Fri, 16 Apr 2021 22:12:00 GMT From: Richard Scheffenegger <rscheff@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: d20563819b92 - stable/11 - tcp: Make hostcache.cache_count MPSAFE by using a counter_u64_t Message-ID: <202104162212.13GMC0oD087210@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/11 has been updated by rscheff: URL: https://cgit.FreeBSD.org/src/commit/?id=d20563819b9292ddcd42caf3449636b84825b1d6 commit d20563819b9292ddcd42caf3449636b84825b1d6 Author: Richard Scheffenegger <rscheff@FreeBSD.org> AuthorDate: 2021-03-31 17:30:20 +0000 Commit: Richard Scheffenegger <rscheff@FreeBSD.org> CommitDate: 2021-04-16 21:33:31 +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 (cherry picked from commit 95e56d31e348594973affd0ea81d8f8383bc3031) --- 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 c4d51dd0bd59..0b5a212c4897 100644 --- a/sys/netinet/tcp_hostcache.c +++ b/sys/netinet/tcp_hostcache.c @@ -144,8 +144,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, @@ -194,7 +194,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; @@ -262,6 +263,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); @@ -369,7 +373,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 @@ -386,7 +390,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); @@ -419,7 +423,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; @@ -633,7 +637,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)); } @@ -705,7 +709,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 44875ff68f6e..4eddfaa806c5 100644 --- a/sys/netinet/tcp_hostcache.h +++ b/sys/netinet/tcp_hostcache.h @@ -67,16 +67,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_*/
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202104162212.13GMC0oD087210>