mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
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
This commit is contained in:
parent
5394893269
commit
95e56d31e3
2 changed files with 22 additions and 18 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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_*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue