From owner-dev-commits-src-main@freebsd.org Thu Apr 1 12:51:28 2021 Return-Path: Delivered-To: dev-commits-src-main@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id B3FC55CCF33; Thu, 1 Apr 2021 12:51:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4FB3344mn7z3llN; Thu, 1 Apr 2021 12:51:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 96A3252A2; Thu, 1 Apr 2021 12:51:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 131CpSD0051912; Thu, 1 Apr 2021 12:51:28 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 131CpSGp051911; Thu, 1 Apr 2021 12:51:28 GMT (envelope-from git) Date: Thu, 1 Apr 2021 12:51:28 GMT Message-Id: <202104011251.131CpSGp051911@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Richard Scheffenegger Subject: git: 02f26e98c7f4 - main - tcp: Add hash histogram output and validate bucket length accounting MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: rscheff X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 02f26e98c7f4d43d6bd077421286da455e069146 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-main@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for the main branch of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 Apr 2021 12:51:28 -0000 The branch main has been updated by rscheff: URL: https://cgit.FreeBSD.org/src/commit/?id=02f26e98c7f4d43d6bd077421286da455e069146 commit 02f26e98c7f4d43d6bd077421286da455e069146 Author: Richard Scheffenegger AuthorDate: 2021-04-01 12:44:05 +0000 Commit: Richard Scheffenegger CommitDate: 2021-04-01 12:44:14 +0000 tcp: Add hash histogram output and validate bucket length accounting Provide a histogram output to check, if the hashsize or bucketlimit could be optimized. Also add some basic sanity checks around the accounting of the hash utilization. MFC after: 2 weeks Reviewed By: tuexen, #transport Sponsored by: NetApp, Inc. Differential Revision: https://reviews.freebsd.org/D29506 --- sys/netinet/tcp_hostcache.c | 62 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/sys/netinet/tcp_hostcache.c b/sys/netinet/tcp_hostcache.c index 87023cc1a760..36439e90a611 100644 --- a/sys/netinet/tcp_hostcache.c +++ b/sys/netinet/tcp_hostcache.c @@ -121,6 +121,7 @@ VNET_DEFINE_STATIC(struct callout, tcp_hc_callout); static struct hc_metrics *tcp_hc_lookup(struct in_conninfo *); static struct hc_metrics *tcp_hc_insert(struct in_conninfo *); 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); static void tcp_hc_purge_internal(int); static void tcp_hc_purge(void *); @@ -168,6 +169,11 @@ SYSCTL_PROC(_net_inet_tcp_hostcache, OID_AUTO, list, 0, 0, sysctl_tcp_hc_list, "A", "List of all hostcache entries"); +SYSCTL_PROC(_net_inet_tcp_hostcache, OID_AUTO, histo, + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_SKIP | CTLFLAG_MPSAFE, + 0, 0, sysctl_tcp_hc_histo, "A", + "Print a histogram of hostcache hashbucket utilization"); + SYSCTL_PROC(_net_inet_tcp_hostcache, OID_AUTO, purgenow, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 0, sysctl_tcp_hc_purgenow, "I", @@ -390,6 +396,11 @@ tcp_hc_insert(struct in_conninfo *inc) return NULL; } TAILQ_REMOVE(&hc_head->hch_bucket, hc_entry, rmx_q); + KASSERT(V_tcp_hostcache.hashbase[hash].hch_length > 0 && + V_tcp_hostcache.hashbase[hash].hch_length <= + V_tcp_hostcache.bucket_limit, + ("tcp_hostcache: bucket length range violated at %u: %u", + hash, V_tcp_hostcache.hashbase[hash].hch_length)); V_tcp_hostcache.hashbase[hash].hch_length--; atomic_subtract_int(&V_tcp_hostcache.cache_count, 1); TCPSTAT_INC(tcps_hc_bucketoverflow); @@ -424,6 +435,10 @@ 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++; + KASSERT(V_tcp_hostcache.hashbase[hash].hch_length < + V_tcp_hostcache.bucket_limit, + ("tcp_hostcache: bucket length too high at %u: %u", + hash, V_tcp_hostcache.hashbase[hash].hch_length)); atomic_add_int(&V_tcp_hostcache.cache_count, 1); TCPSTAT_INC(tcps_hc_added); @@ -696,6 +711,48 @@ sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS) return(error); } +/* + * Sysctl function: prints a histogram of the hostcache hashbucket + * utilization. + */ +static int +sysctl_tcp_hc_histo(SYSCTL_HANDLER_ARGS) +{ + const int linesize = 50; + struct sbuf sb; + int i, error; + int *histo; + u_int hch_length; + + if (jailed_without_vnet(curthread->td_ucred) != 0) + return (EPERM); + + histo = (int *)malloc(sizeof(int) * (V_tcp_hostcache.bucket_limit + 1), + M_TEMP, M_NOWAIT|M_ZERO); + if (histo == NULL) + return(ENOMEM); + + for (i = 0; i < V_tcp_hostcache.hashsize; i++) { + hch_length = V_tcp_hostcache.hashbase[i].hch_length; + KASSERT(hch_length <= V_tcp_hostcache.bucket_limit, + ("tcp_hostcache: bucket limit exceeded at %u: %u", + i, hch_length)); + histo[hch_length]++; + } + + /* Use a buffer for 16 lines */ + sbuf_new_for_sysctl(&sb, NULL, 16 * linesize, req); + + sbuf_printf(&sb, "\nLength\tCount\n"); + for (i = 0; i <= V_tcp_hostcache.bucket_limit; i++) { + sbuf_printf(&sb, "%u\t%u\n", i, histo[i]); + } + error = sbuf_finish(&sb); + sbuf_delete(&sb); + free(histo, M_TEMP); + return(error); +} + /* * Caller has to make sure the curvnet is set properly. */ @@ -709,6 +766,11 @@ tcp_hc_purge_internal(int all) THC_LOCK(&V_tcp_hostcache.hashbase[i].hch_mtx); TAILQ_FOREACH_SAFE(hc_entry, &V_tcp_hostcache.hashbase[i].hch_bucket, rmx_q, hc_next) { + KASSERT(V_tcp_hostcache.hashbase[i].hch_length > 0 && + V_tcp_hostcache.hashbase[i].hch_length <= + V_tcp_hostcache.bucket_limit, + ("tcp_hostcache: bucket langth out of range at %u: %u", + i, V_tcp_hostcache.hashbase[i].hch_length)); if (all || hc_entry->rmx_expire <= 0) { TAILQ_REMOVE(&V_tcp_hostcache.hashbase[i].hch_bucket, hc_entry, rmx_q);