]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Convert ns/stats.c to statsmulti
authorAlessio Podda <alessio@isc.org>
Tue, 9 Sep 2025 14:22:46 +0000 (16:22 +0200)
committerAlessio Podda <alessio@isc.org>
Wed, 24 Sep 2025 15:01:49 +0000 (17:01 +0200)
bin/named/server.c
bin/named/statschannel.c
lib/dns/stats.c
lib/isc/include/isc/statsmulti.h
lib/isc/statsmulti.c
lib/ns/include/ns/server.h
lib/ns/include/ns/stats.h
lib/ns/server.c
lib/ns/stats.c

index 1a2ef75acce42ad397939a925c75561414692456..fc85c87d1206fe450470a617ad379f7bf77fb5f8 100644 (file)
@@ -10546,12 +10546,12 @@ named_server_resetstatscommand(named_server_t *server, isc_lex_t *lex,
        }
 
        if (recursive_high_water) {
-               isc_stats_set(ns_stats_get(server->sctx->nsstats), 0,
-                             ns_statscounter_recurshighwater);
+               ns_stats_reset_highwater(server->sctx->nsstats,
+                                         ns_statscounter_recurshighwater);
        }
        if (tcp_high_water) {
-               isc_stats_set(ns_stats_get(server->sctx->nsstats), 0,
-                             ns_statscounter_tcphighwater);
+               ns_stats_reset_highwater(server->sctx->nsstats,
+                                         ns_statscounter_tcphighwater);
        }
 
        return ISC_R_SUCCESS;
index 25dcfb4fcd1a9924c06970b26490d6591fdc0a68..a1929ee2cc4f26d56748044e9a8f8b0080bb907d 100644 (file)
@@ -837,6 +837,30 @@ dump_stats(isc_stats_t *stats, isc_statsformat_t type, void *arg,
                             values, options);
 }
 
+static isc_result_t
+dump_statsmulti(isc_statsmulti_t *stats, isc_statsformat_t type, void *arg,
+               const char *category, const char **desc, int ncounters,
+               int *indices, uint64_t *values, int options) {
+       stats_dumparg_t dumparg;
+       unsigned int multioptions = 0;
+
+       dumparg.type = type;
+       dumparg.ncounters = ncounters;
+       dumparg.counterindices = indices;
+       dumparg.countervalues = values;
+
+       /* Convert ISC_STATSDUMP_VERBOSE to ISC_STATSMULTIDUMP_VERBOSE */
+       if ((options & ISC_STATSDUMP_VERBOSE) != 0) {
+               multioptions |= ISC_STATSMULTIDUMP_VERBOSE;
+       }
+
+       memset(values, 0, sizeof(values[0]) * ncounters);
+       isc_statsmulti_dump(stats, generalstat_dump, &dumparg, multioptions);
+
+       return dump_counters(type, arg, category, desc, ncounters, indices,
+                            values, options);
+}
+
 #if defined(EXTENDED_STATS)
 static isc_result_t
 dump_histo(isc_histomulti_t *hm, isc_statsformat_t type, void *arg,
@@ -1852,11 +1876,11 @@ generatexml(named_server_t *server, uint32_t flags, int *buflen,
                TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
                                                 ISC_XMLCHAR "nsstat"));
 
-               CHECK(dump_stats(ns_stats_get(server->sctx->nsstats),
-                                isc_statsformat_xml, writer, NULL,
-                                nsstats_xmldesc, ns_statscounter_max,
-                                nsstats_index, nsstat_values,
-                                ISC_STATSDUMP_VERBOSE));
+               CHECK(dump_statsmulti(server->sctx->nsstats,
+                                     isc_statsformat_xml, writer, NULL,
+                                     nsstats_xmldesc, ns_statscounter_max,
+                                     nsstats_index, nsstat_values,
+                                     ISC_STATSDUMP_VERBOSE));
 
                TRY0(xmlTextWriterEndElement(writer)); /* /nsstat */
 
@@ -2940,10 +2964,10 @@ generatejson(named_server_t *server, size_t *msglen, const char **msg,
                dumparg.result = ISC_R_SUCCESS;
                dumparg.arg = counters;
 
-               result = dump_stats(ns_stats_get(server->sctx->nsstats),
-                                   isc_statsformat_json, counters, NULL,
-                                   nsstats_xmldesc, ns_statscounter_max,
-                                   nsstats_index, nsstat_values, 0);
+               result = dump_statsmulti(server->sctx->nsstats,
+                                        isc_statsformat_json, counters, NULL,
+                                        nsstats_xmldesc, ns_statscounter_max,
+                                        nsstats_index, nsstat_values, 0);
                if (result != ISC_R_SUCCESS) {
                        json_object_put(counters);
                        goto cleanup;
@@ -3988,9 +4012,10 @@ named_stats_dump(named_server_t *server, FILE *fp) {
        }
 
        fprintf(fp, "++ Name Server Statistics ++\n");
-       (void)dump_stats(ns_stats_get(server->sctx->nsstats),
-                        isc_statsformat_file, fp, NULL, nsstats_desc,
-                        ns_statscounter_max, nsstats_index, nsstat_values, 0);
+       (void)dump_statsmulti(server->sctx->nsstats,
+                             isc_statsformat_file, fp, NULL, nsstats_desc,
+                             ns_statscounter_max, nsstats_index,
+                             nsstat_values, 0);
 
        fprintf(fp, "++ Zone Maintenance Statistics ++\n");
        (void)dump_stats(server->zonestats, isc_statsformat_file, fp, NULL,
index 2a77b01c4e8e75426d65af89386057981cd4a8af..c030f3db15898aa4f23f6a45aa6ced3af47fe08f 100644 (file)
@@ -197,6 +197,7 @@ dns_rdatatypestats_create(isc_mem_t *mctx, isc_statsmulti_t **statsp) {
         * Create rdtype statistics using statsmulti for better multithreading performance.
         * We need RDTYPECOUNTER_MAXVAL + 1 counters (0x0602 + 1 = 1539 counters).
         */
+       // XXX(ap): Fix this, this is wrong!
        isc_statsmulti_create(mctx, statsp, RDTYPECOUNTER_MAXVAL + 1, 0);
 }
 
index 0b2a50cc5eff9e6d8053e1019551d42ddd525c8c..379710775b673eaea9fb9f3f6e2289acb48e3da3 100644 (file)
@@ -141,4 +141,16 @@ isc_statsmulti_get_highwater(isc_statsmulti_t *stats, isc_statscounter_t counter
  *\li  'stats' is a valid isc_statsmulti_t.
  *
  *\li  counter is less than n_max specified on creation.
+ */
+
+void
+isc_statsmulti_reset_highwater(isc_statsmulti_t *stats, isc_statscounter_t counter);
+/*%<
+ * Reset a highwater counter to zero across all threads.
+ * Takes counter values from 0 to n_max-1 and internally maps to the highwater range.
+ *
+ * Requires:
+ *\li  'stats' is a valid isc_statsmulti_t.
+ *
+ *\li  counter is less than n_max specified on creation.
  */
\ No newline at end of file
index 4365e4ba79258f43b04ecb9386159ae41841b2a1..7014a97b33cb48d743324dcf8a5701eca8a19bc7 100644 (file)
@@ -180,7 +180,8 @@ isc_statsmulti_clear(isc_statsmulti_t *stats) {
 void
 isc_statsmulti_update_if_greater(isc_statsmulti_t *stats, isc_statscounter_t counter, isc_statscounter_t value) {
        REQUIRE(ISC_STATSMULTI_VALID(stats));
-       REQUIRE(counter < stats->n_max);
+       REQUIRE(counter >= stats->n_additive);
+       REQUIRE(counter < stats->ncounters);
 
        /* Map counter to internal highwater position */
        isc_statscounter_t internal_counter = stats->n_additive + counter;
@@ -205,7 +206,8 @@ isc_statsmulti_update_if_greater(isc_statsmulti_t *stats, isc_statscounter_t cou
 isc_statscounter_t
 isc_statsmulti_get_highwater(isc_statsmulti_t *stats, isc_statscounter_t counter) {
        REQUIRE(ISC_STATSMULTI_VALID(stats));
-       REQUIRE(counter < stats->n_max);
+       REQUIRE(counter >= stats->n_additive);
+       REQUIRE(counter < stats->ncounters);
 
        /* Map counter to internal highwater position */
        isc_statscounter_t internal_counter = stats->n_additive + counter;
@@ -221,3 +223,19 @@ isc_statsmulti_get_highwater(isc_statsmulti_t *stats, isc_statscounter_t counter
        }
        return max_value;
 }
+
+void
+isc_statsmulti_reset_highwater(isc_statsmulti_t *stats, isc_statscounter_t counter) {
+       REQUIRE(ISC_STATSMULTI_VALID(stats));
+       REQUIRE(counter >= stats->n_additive);
+       REQUIRE(counter < stats->ncounters);
+
+       /* Map counter to internal highwater position */
+       isc_statscounter_t internal_counter = stats->n_additive + counter;
+
+       /* Reset highwater counter to 0 across all threads */
+       for (int thread = 0; thread < stats->num_threads; thread++) {
+               int index = thread * stats->per_thread_capacity + internal_counter;
+               atomic_store_relaxed(&stats->counters[index], 0);
+       }
+}
index cf1bc0161c4f61a78eee64999f60e46ca92f0d09..9259d535668ec0d98a1ae1b9cd74af95076a3d30 100644 (file)
@@ -121,7 +121,7 @@ struct ns_server {
        ns_matchview_t matchingview;
 
        /*% Stats counters */
-       ns_stats_t       *nsstats;
+       isc_statsmulti_t *nsstats;
        isc_statsmulti_t *rcvquerystats;
        dns_stats_t      *opcodestats;
        dns_stats_t      *rcodestats;
index 496e4cd9a549876eb04faddb2c538b3396564238..cd6bc1f8b75cd933776c77b379b37ed0df402486 100644 (file)
 
 #include <isc/mem.h>
 #include <isc/stats.h>
+#include <isc/statsmulti.h>
 
 #include <ns/types.h>
 
+// XXX(ap): additive counters
 /*%
  * Server statistics counters.  Used as isc_statscounter_t values.
  */
@@ -107,50 +109,54 @@ enum {
        ns_statscounter_prefetch = 64,
        ns_statscounter_keytagopt = 65,
 
-       ns_statscounter_tcphighwater = 66,
+       ns_statscounter_reclimitdropped = 66,
 
-       ns_statscounter_reclimitdropped = 67,
+       ns_statscounter_updatequota = 67,
+       ns_statscounter_dot = 68,
+       ns_statscounter_doh = 69,
+       ns_statscounter_dohplain = 70,
 
-       ns_statscounter_updatequota = 68,
-
-       ns_statscounter_recurshighwater = 69,
-
-       ns_statscounter_dot = 70,
-       ns_statscounter_doh = 71,
-       ns_statscounter_dohplain = 72,
-
-       ns_statscounter_proxyudp = 73,
-       ns_statscounter_proxytcp = 74,
-       ns_statscounter_proxydot = 75,
-       ns_statscounter_proxydoh = 76,
-       ns_statscounter_proxydohplain = 77,
-       ns_statscounter_encryptedproxydot = 78,
-       ns_statscounter_encryptedproxydoh = 79,
+       ns_statscounter_proxyudp = 71,
+       ns_statscounter_proxytcp = 72,
+       ns_statscounter_proxydot = 73,
+       ns_statscounter_proxydoh = 74,
+       ns_statscounter_proxydohplain = 75,
+       ns_statscounter_encryptedproxydot = 76,
+       ns_statscounter_encryptedproxydoh = 77,
 
        ns_statscounter_max = 80,
 };
 
-void
-ns_stats_attach(ns_stats_t *stats, ns_stats_t **statsp);
+// XXX(ap): highwater counters
+enum {
+       ns_statscounter_tcphighwater = 78,
+       ns_statscounter_recurshighwater = 79,
 
-void
-ns_stats_detach(ns_stats_t **statsp);
+       ns_highwater_max = ns_statscounter_max,
+};
+
+enum {
+       ns_statscounter_total = ns_statscounter_max + ns_highwater_max,
+};
 
 void
-ns_stats_create(isc_mem_t *mctx, int ncounters, ns_stats_t **statsp);
+ns_stats_create(isc_mem_t *mctx, isc_statsmulti_t **statsp);
 
 isc_statscounter_t
-ns_stats_increment(ns_stats_t *stats, isc_statscounter_t counter);
+ns_stats_increment(isc_statsmulti_t *stats, isc_statscounter_t counter);
 
 void
-ns_stats_decrement(ns_stats_t *stats, isc_statscounter_t counter);
-
-isc_stats_t *
-ns_stats_get(ns_stats_t *stats);
+ns_stats_decrement(isc_statsmulti_t *stats, isc_statscounter_t counter);
 
 void
-ns_stats_update_if_greater(ns_stats_t *stats, isc_statscounter_t counter,
+ns_stats_update_if_greater(isc_statsmulti_t *stats, isc_statscounter_t counter,
                           isc_statscounter_t value);
 
 isc_statscounter_t
-ns_stats_get_counter(ns_stats_t *stats, isc_statscounter_t counter);
+ns_stats_get_counter(isc_statsmulti_t *stats, isc_statscounter_t counter);
+
+isc_statscounter_t
+ns_stats_get_highwater(isc_statsmulti_t *stats, isc_statscounter_t counter);
+
+void
+ns_stats_reset_highwater(isc_statsmulti_t *stats, isc_statscounter_t counter);
index 48a2bd2f3a75a1a90f5fd07da91c80fca5f61d8f..97a5dcc0eaf2a0c2bf41e4e028249e3223d1252d 100644 (file)
@@ -70,7 +70,7 @@ ns_server_create(isc_mem_t *mctx, ns_matchview_t matchingview,
        ISC_LIST_INIT(sctx->http_quotas);
        isc_mutex_init(&sctx->http_quotas_lock);
 
-       ns_stats_create(mctx, ns_statscounter_max, &sctx->nsstats);
+       ns_stats_create(mctx, &sctx->nsstats);
 
        dns_rdatatypestats_create(mctx, &sctx->rcvquerystats);
 
@@ -162,7 +162,7 @@ ns_server_detach(ns_server_t **sctxp) {
                }
 
                if (sctx->nsstats != NULL) {
-                       ns_stats_detach(&sctx->nsstats);
+                       isc_statsmulti_detach(&sctx->nsstats);
                }
 
                if (sctx->rcvquerystats != NULL) {
index 6bc7c1f34641be012597a5be13dfcf93d48d3e03..ad287aef439d9f9cacd1e3c389dfe8b0e0dcdd63 100644 (file)
 
 /*! \file */
 
-#include <isc/magic.h>
 #include <isc/mem.h>
-#include <isc/refcount.h>
-#include <isc/stats.h>
+#include <isc/statsmulti.h>
 #include <isc/util.h>
 
 #include <ns/stats.h>
 
-#define NS_STATS_MAGIC   ISC_MAGIC('N', 's', 't', 't')
-#define NS_STATS_VALID(x) ISC_MAGIC_VALID(x, NS_STATS_MAGIC)
-
-struct ns_stats {
-       /*% Unlocked */
-       unsigned int magic;
-       isc_mem_t *mctx;
-       isc_stats_t *counters;
-       isc_refcount_t references;
-};
-
 void
-ns_stats_attach(ns_stats_t *stats, ns_stats_t **statsp) {
-       REQUIRE(NS_STATS_VALID(stats));
+ns_stats_create(isc_mem_t *mctx, isc_statsmulti_t **statsp) {
        REQUIRE(statsp != NULL && *statsp == NULL);
 
-       isc_refcount_increment(&stats->references);
-
-       *statsp = stats;
-}
-
-void
-ns_stats_detach(ns_stats_t **statsp) {
-       ns_stats_t *stats;
-
-       REQUIRE(statsp != NULL && NS_STATS_VALID(*statsp));
-
-       stats = *statsp;
-       *statsp = NULL;
-
-       if (isc_refcount_decrement(&stats->references) == 1) {
-               isc_stats_detach(&stats->counters);
-               isc_refcount_destroy(&stats->references);
-               isc_mem_putanddetach(&stats->mctx, stats, sizeof(*stats));
-       }
-}
-
-void
-ns_stats_create(isc_mem_t *mctx, int ncounters, ns_stats_t **statsp) {
-       REQUIRE(statsp != NULL && *statsp == NULL);
-
-       ns_stats_t *stats = isc_mem_get(mctx, sizeof(*stats));
-       stats->counters = NULL;
-
-       isc_refcount_init(&stats->references, 1);
-
-       isc_stats_create(mctx, &stats->counters, ncounters);
-
-       stats->magic = NS_STATS_MAGIC;
-       stats->mctx = NULL;
-       isc_mem_attach(mctx, &stats->mctx);
-       *statsp = stats;
+       /*
+        * Create ns statistics using statsmulti for better multithreading performance.
+        * We have 78 additive counters and ns_highwater_max highwater counters.
+        */
+       isc_statsmulti_create(mctx, statsp, 78, 2);
 }
 
 /*%
  * Increment/Decrement methods
  */
 isc_statscounter_t
-ns_stats_increment(ns_stats_t *stats, isc_statscounter_t counter) {
-       REQUIRE(NS_STATS_VALID(stats));
+ns_stats_increment(isc_statsmulti_t *stats, isc_statscounter_t counter) {
+       REQUIRE(stats != NULL);
 
-       return isc_stats_increment(stats->counters, counter);
+       return isc_statsmulti_increment(stats, counter);
 }
 
 void
-ns_stats_decrement(ns_stats_t *stats, isc_statscounter_t counter) {
-       REQUIRE(NS_STATS_VALID(stats));
+ns_stats_decrement(isc_statsmulti_t *stats, isc_statscounter_t counter) {
+       REQUIRE(stats != NULL);
 
-       isc_stats_decrement(stats->counters, counter);
+       isc_statsmulti_decrement(stats, counter);
 }
 
-isc_stats_t *
-ns_stats_get(ns_stats_t *stats) {
-       REQUIRE(NS_STATS_VALID(stats));
+void
+ns_stats_update_if_greater(isc_statsmulti_t *stats, isc_statscounter_t counter,
+                          isc_statscounter_t value) {
+       REQUIRE(stats != NULL);
 
-       return stats->counters;
+       isc_statsmulti_update_if_greater(stats, counter, value);
 }
 
-void
-ns_stats_update_if_greater(ns_stats_t *stats, isc_statscounter_t counter,
-                          isc_statscounter_t value) {
-       REQUIRE(NS_STATS_VALID(stats));
+isc_statscounter_t
+ns_stats_get_counter(isc_statsmulti_t *stats, isc_statscounter_t counter) {
+       REQUIRE(stats != NULL);
+
+       /* Check if this is a highwater counter */
+       if (counter == ns_statscounter_tcphighwater || counter == ns_statscounter_recurshighwater) {
+               return ns_stats_get_highwater(stats, counter);
+       }
 
-       isc_stats_update_if_greater(stats->counters, counter, value);
+       return isc_statsmulti_get_counter(stats, counter);
 }
 
 isc_statscounter_t
-ns_stats_get_counter(ns_stats_t *stats, isc_statscounter_t counter) {
-       REQUIRE(NS_STATS_VALID(stats));
+ns_stats_get_highwater(isc_statsmulti_t *stats, isc_statscounter_t counter) {
+       REQUIRE(stats != NULL);
+
+       return isc_statsmulti_get_highwater(stats, counter);
+}
+
+void
+ns_stats_reset_highwater(isc_statsmulti_t *stats, isc_statscounter_t counter) {
+       REQUIRE(stats != NULL);
 
-       return isc_stats_get_counter(stats->counters, counter);
+       isc_statsmulti_reset_highwater(stats, counter);
 }