Add a dedicated metrics entry for each coverage counter registered.
The set of counters is accessed through a collection. As a result,
all entries have the same metrics name, only differing by their
label "name".

Considering the volume of entries, they are only generated in the
metrics debug page.

Signed-off-by: Gaetan Rivet <[email protected]>
---
 lib/automake.mk        |  2 ++
 lib/coverage-metrics.c | 65 ++++++++++++++++++++++++++++++++++++++++++
 lib/coverage-private.h | 31 ++++++++++++++++++++
 lib/coverage.c         | 10 ++++---
 4 files changed, 104 insertions(+), 4 deletions(-)
 create mode 100644 lib/coverage-metrics.c
 create mode 100644 lib/coverage-private.h

diff --git a/lib/automake.mk b/lib/automake.mk
index 0b69354bc4..ff657f3cc0 100644
--- a/lib/automake.mk
+++ b/lib/automake.mk
@@ -99,6 +99,8 @@ lib_libopenvswitch_la_SOURCES = \
        lib/cooperative-multitasking-private.h \
        lib/coverage.c \
        lib/coverage.h \
+       lib/coverage-metrics.c \
+       lib/coverage-private.h \
        lib/cpu.c \
        lib/cpu.h \
        lib/crc32c.c \
diff --git a/lib/coverage-metrics.c b/lib/coverage-metrics.c
new file mode 100644
index 0000000000..38638df54a
--- /dev/null
+++ b/lib/coverage-metrics.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+
+#include "coverage.h"
+#include "coverage-private.h"
+#include "metrics.h"
+
+static void
+do_foreach_coverage_counter(metrics_visitor_cb callback,
+                            struct metrics_visitor *visitor,
+                            struct metrics_node *node,
+                            struct metrics_label *labels,
+                            size_t n_labels OVS_UNUSED)
+{
+    struct coverage_counter *c;
+    size_t i;
+
+    ovs_mutex_lock(&coverage_mutex);
+    for (i = 0; i < n_coverage_counters; i++) {
+        c = coverage_counters[i];
+        labels[0].value = c->name;
+        visitor->it = c;
+        callback(visitor, node);
+    }
+    ovs_mutex_unlock(&coverage_mutex);
+}
+
+static void
+coverage_metrics_read(double *value, void *c_)
+{
+    struct coverage_counter *c = c_;
+
+    c->total += c->count();
+    *value = c->total;
+}
+
+METRICS_SUBSYSTEM(coverage);
+METRICS_IF(coverage, coverage_dbg, metrics_dbg_enabled);
+METRICS_FOREACH(coverage_dbg, foreach_coverage_counter_dbg,
+                do_foreach_coverage_counter, "counter");
+METRICS_ENTRIES(foreach_coverage_counter_dbg, coverage_entries,
+        "coverage", coverage_metrics_read,
+        [0] = METRICS_COUNTER(, "Coverage counters labeled by their name."),
+);
+
+void
+coverage_metrics_init(void)
+{
+    METRICS_REGISTER(coverage_entries);
+}
diff --git a/lib/coverage-private.h b/lib/coverage-private.h
new file mode 100644
index 0000000000..71e95b5f92
--- /dev/null
+++ b/lib/coverage-private.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef COVERAGE_PRIVATE_H
+#define COVERAGE_PRIVATE_H 1
+
+#include "coverage.h"
+
+/* The coverage counters. */
+extern struct coverage_counter **coverage_counters;
+extern size_t n_coverage_counters;
+extern size_t allocated_coverage_counters;
+
+extern struct ovs_mutex coverage_mutex;
+
+void coverage_metrics_init(void);
+
+#endif /* COVERAGE_PRIVATE_H */
diff --git a/lib/coverage.c b/lib/coverage.c
index a95b6aa255..7f2a1296ae 100644
--- a/lib/coverage.c
+++ b/lib/coverage.c
@@ -16,6 +16,7 @@
 
 #include <config.h>
 #include "coverage.h"
+#include "coverage-private.h"
 #include <inttypes.h>
 #include <stdlib.h>
 #include "openvswitch/dynamic-string.h"
@@ -29,11 +30,11 @@
 VLOG_DEFINE_THIS_MODULE(coverage);
 
 /* The coverage counters. */
-static struct coverage_counter **coverage_counters = NULL;
-static size_t n_coverage_counters = 0;
-static size_t allocated_coverage_counters = 0;
+struct coverage_counter **coverage_counters = NULL;
+size_t n_coverage_counters = 0;
+size_t allocated_coverage_counters = 0;
 
-static struct ovs_mutex coverage_mutex = OVS_MUTEX_INITIALIZER;
+struct ovs_mutex coverage_mutex = OVS_MUTEX_INITIALIZER;
 
 DEFINE_STATIC_PER_THREAD_DATA(long long int, coverage_clear_time, LLONG_MIN);
 static long long int coverage_run_time = LLONG_MIN;
@@ -100,6 +101,7 @@ coverage_init(void)
                              coverage_unixctl_show, NULL);
     unixctl_command_register("coverage/read-counter", "COUNTER", 1, 1,
                              coverage_unixctl_read_counter, NULL);
+    coverage_metrics_init();
 }
 
 /* Sorts coverage counters in descending order by total, within equal
-- 
2.34.1

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to