mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-22 10:10:14 -04:00
In the current statistics counter implementation, the statistics are backed by an array of counters, which are updated via atomic operations. This leads to contention, especially on high core count machines. This commit introduces a new isc_statsmulti_t counter that keeps a separate array per thread. These counters are then aggregated only when statistics are queried, shifting work off the critical path. These changes lead to a ~2% improvement in perflab.
255 lines
6.2 KiB
C
255 lines
6.2 KiB
C
/*
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
|
*
|
|
* SPDX-License-Identifier: MPL-2.0
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*
|
|
* See the COPYRIGHT file distributed with this work for additional
|
|
* information regarding copyright ownership.
|
|
*/
|
|
|
|
/*! \file */
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <isc/mem.h>
|
|
#include <isc/stats.h>
|
|
#include <isc/util.h>
|
|
|
|
#include <dns/stats.h>
|
|
#include <dns/tkey.h>
|
|
|
|
#include <ns/query.h>
|
|
#include <ns/server.h>
|
|
#include <ns/stats.h>
|
|
|
|
#define SCTX_MAGIC ISC_MAGIC('S', 'c', 't', 'x')
|
|
#define SCTX_VALID(s) ISC_MAGIC_VALID(s, SCTX_MAGIC)
|
|
|
|
#define CHECKFATAL(op) \
|
|
do { \
|
|
result = (op); \
|
|
RUNTIME_CHECK(result == ISC_R_SUCCESS); \
|
|
} while (0)
|
|
|
|
void
|
|
ns_server_create(isc_mem_t *mctx, ns_matchview_t matchingview,
|
|
ns_server_t **sctxp) {
|
|
ns_server_t *sctx = NULL;
|
|
|
|
REQUIRE(sctxp != NULL && *sctxp == NULL);
|
|
|
|
sctx = isc_mem_get(mctx, sizeof(*sctx));
|
|
*sctx = (ns_server_t){
|
|
.udpsize = 1232,
|
|
.transfer_tcp_message_size = 20480,
|
|
|
|
.fuzztype = isc_fuzz_none,
|
|
|
|
.matchingview = matchingview,
|
|
.answercookie = true,
|
|
};
|
|
|
|
isc_mem_attach(mctx, &sctx->mctx);
|
|
|
|
/*
|
|
* See here for more details:
|
|
* https://github.com/jemalloc/jemalloc/issues/2483
|
|
*/
|
|
|
|
isc_refcount_init(&sctx->references, 1);
|
|
|
|
isc_quota_init(&sctx->xfroutquota, 10);
|
|
isc_quota_init(&sctx->tcpquota, 10);
|
|
isc_quota_init(&sctx->recursionquota, 100);
|
|
isc_quota_init(&sctx->updquota, 100);
|
|
isc_quota_init(&sctx->sig0checksquota, 1);
|
|
ISC_LIST_INIT(sctx->http_quotas);
|
|
isc_mutex_init(&sctx->http_quotas_lock);
|
|
|
|
ns_stats_create(mctx, &sctx->nsstats, &sctx->nshighwaterstats);
|
|
|
|
dns_rdatatypestats_create(mctx, &sctx->rcvquerystats);
|
|
|
|
dns_opcodestats_create(mctx, &sctx->opcodestats);
|
|
|
|
dns_rcodestats_create(mctx, &sctx->rcodestats);
|
|
|
|
isc_histomulti_create(mctx, DNS_SIZEHISTO_SIGBITSIN,
|
|
&sctx->udpinstats4);
|
|
|
|
isc_histomulti_create(mctx, DNS_SIZEHISTO_SIGBITSOUT,
|
|
&sctx->udpoutstats4);
|
|
|
|
isc_histomulti_create(mctx, DNS_SIZEHISTO_SIGBITSIN,
|
|
&sctx->udpinstats6);
|
|
|
|
isc_histomulti_create(mctx, DNS_SIZEHISTO_SIGBITSOUT,
|
|
&sctx->udpoutstats6);
|
|
|
|
isc_histomulti_create(mctx, DNS_SIZEHISTO_SIGBITSIN,
|
|
&sctx->tcpinstats4);
|
|
|
|
isc_histomulti_create(mctx, DNS_SIZEHISTO_SIGBITSOUT,
|
|
&sctx->tcpoutstats4);
|
|
|
|
isc_histomulti_create(mctx, DNS_SIZEHISTO_SIGBITSIN,
|
|
&sctx->tcpinstats6);
|
|
|
|
isc_histomulti_create(mctx, DNS_SIZEHISTO_SIGBITSOUT,
|
|
&sctx->tcpoutstats6);
|
|
|
|
ISC_LIST_INIT(sctx->altsecrets);
|
|
|
|
sctx->magic = SCTX_MAGIC;
|
|
*sctxp = sctx;
|
|
}
|
|
|
|
void
|
|
ns_server_attach(ns_server_t *src, ns_server_t **dest) {
|
|
REQUIRE(SCTX_VALID(src));
|
|
REQUIRE(dest != NULL && *dest == NULL);
|
|
|
|
isc_refcount_increment(&src->references);
|
|
|
|
*dest = src;
|
|
}
|
|
|
|
void
|
|
ns_server_detach(ns_server_t **sctxp) {
|
|
ns_server_t *sctx;
|
|
|
|
REQUIRE(sctxp != NULL && SCTX_VALID(*sctxp));
|
|
sctx = *sctxp;
|
|
*sctxp = NULL;
|
|
|
|
if (isc_refcount_decrement(&sctx->references) == 1) {
|
|
ISC_LIST_FOREACH(sctx->altsecrets, altsecret, link) {
|
|
ISC_LIST_UNLINK(sctx->altsecrets, altsecret, link);
|
|
isc_mem_put(sctx->mctx, altsecret, sizeof(*altsecret));
|
|
}
|
|
|
|
if (sctx->sig0checksquota_exempt != NULL) {
|
|
dns_acl_detach(&sctx->sig0checksquota_exempt);
|
|
}
|
|
|
|
isc_quota_destroy(&sctx->sig0checksquota);
|
|
isc_quota_destroy(&sctx->updquota);
|
|
isc_quota_destroy(&sctx->recursionquota);
|
|
isc_quota_destroy(&sctx->tcpquota);
|
|
isc_quota_destroy(&sctx->xfroutquota);
|
|
|
|
ISC_LIST_FOREACH(sctx->http_quotas, http_quota, link) {
|
|
ISC_LIST_DEQUEUE(sctx->http_quotas, http_quota, link);
|
|
isc_quota_destroy(http_quota);
|
|
isc_mem_put(sctx->mctx, http_quota,
|
|
sizeof(*http_quota));
|
|
}
|
|
isc_mutex_destroy(&sctx->http_quotas_lock);
|
|
|
|
if (sctx->server_id != NULL) {
|
|
isc_mem_free(sctx->mctx, sctx->server_id);
|
|
}
|
|
|
|
if (sctx->blackholeacl != NULL) {
|
|
dns_acl_detach(&sctx->blackholeacl);
|
|
}
|
|
if (sctx->tkeyctx != NULL) {
|
|
dns_tkeyctx_destroy(&sctx->tkeyctx);
|
|
}
|
|
|
|
if (sctx->nsstats != NULL) {
|
|
isc_statsmulti_detach(&sctx->nsstats);
|
|
}
|
|
|
|
if (sctx->nshighwaterstats != NULL) {
|
|
isc_stats_detach(&sctx->nshighwaterstats);
|
|
}
|
|
|
|
if (sctx->rcvquerystats != NULL) {
|
|
isc_statsmulti_detach(&sctx->rcvquerystats);
|
|
}
|
|
if (sctx->opcodestats != NULL) {
|
|
isc_statsmulti_detach(&sctx->opcodestats);
|
|
}
|
|
if (sctx->rcodestats != NULL) {
|
|
isc_statsmulti_detach(&sctx->rcodestats);
|
|
}
|
|
|
|
if (sctx->udpinstats4 != NULL) {
|
|
isc_histomulti_detach(&sctx->udpinstats4);
|
|
}
|
|
if (sctx->tcpinstats4 != NULL) {
|
|
isc_histomulti_detach(&sctx->tcpinstats4);
|
|
}
|
|
if (sctx->udpoutstats4 != NULL) {
|
|
isc_histomulti_detach(&sctx->udpoutstats4);
|
|
}
|
|
if (sctx->tcpoutstats4 != NULL) {
|
|
isc_histomulti_detach(&sctx->tcpoutstats4);
|
|
}
|
|
|
|
if (sctx->udpinstats6 != NULL) {
|
|
isc_histomulti_detach(&sctx->udpinstats6);
|
|
}
|
|
if (sctx->tcpinstats6 != NULL) {
|
|
isc_histomulti_detach(&sctx->tcpinstats6);
|
|
}
|
|
if (sctx->udpoutstats6 != NULL) {
|
|
isc_histomulti_detach(&sctx->udpoutstats6);
|
|
}
|
|
if (sctx->tcpoutstats6 != NULL) {
|
|
isc_histomulti_detach(&sctx->tcpoutstats6);
|
|
}
|
|
|
|
sctx->magic = 0;
|
|
|
|
isc_mem_putanddetach(&sctx->mctx, sctx, sizeof(*sctx));
|
|
}
|
|
}
|
|
|
|
isc_result_t
|
|
ns_server_setserverid(ns_server_t *sctx, const char *serverid) {
|
|
REQUIRE(SCTX_VALID(sctx));
|
|
|
|
if (sctx->server_id != NULL) {
|
|
isc_mem_free(sctx->mctx, sctx->server_id);
|
|
}
|
|
|
|
if (serverid != NULL) {
|
|
sctx->server_id = isc_mem_strdup(sctx->mctx, serverid);
|
|
}
|
|
|
|
return ISC_R_SUCCESS;
|
|
}
|
|
|
|
void
|
|
ns_server_setoption(ns_server_t *sctx, unsigned int option, bool value) {
|
|
REQUIRE(SCTX_VALID(sctx));
|
|
if (value) {
|
|
sctx->options |= option;
|
|
} else {
|
|
sctx->options &= ~option;
|
|
}
|
|
}
|
|
|
|
bool
|
|
ns_server_getoption(ns_server_t *sctx, unsigned int option) {
|
|
REQUIRE(SCTX_VALID(sctx));
|
|
|
|
return (sctx->options & option) != 0;
|
|
}
|
|
|
|
void
|
|
ns_server_append_http_quota(ns_server_t *sctx, isc_quota_t *http_quota) {
|
|
REQUIRE(SCTX_VALID(sctx));
|
|
REQUIRE(http_quota != NULL);
|
|
|
|
LOCK(&sctx->http_quotas_lock);
|
|
ISC_LINK_INIT(http_quota, link);
|
|
ISC_LIST_APPEND(sctx->http_quotas, http_quota, link);
|
|
UNLOCK(&sctx->http_quotas_lock);
|
|
}
|