From: Shashank Mohan Jain <jain.sm@gmail.com>
To: "David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>
Cc: netdev@vger.kernel.org, Simon Horman <horms@kernel.org>,
Tal Gilboa <talgi@nvidia.com>, Saeed Mahameed <saeedm@nvidia.com>,
Tariq Toukan <tariqt@nvidia.com>,
Andrew Morton <akpm@linux-foundation.org>,
linux-kernel@vger.kernel.org
Subject: [PATCH net 2/2] lib/dim: add KUnit test for dim_calc_stats()
Date: Sun, 27 Sep 2026 10:47:43 +0530 [thread overview]
Message-ID: <20260927051743.71460-3-jain.sm@gmail.com> (raw)
In-Reply-To: <20260927051743.71460-1-jain.sm@gmail.com>
Add a KUnit suite for the DIM library that checks the packet, byte,
event and completion rates computed by dim_calc_stats(), including
counter wraparound and windows whose byte or packet count times
USEC_PER_MSEC does not fit in 32 bits. The latter cases fail on 32-bit
architectures without the previous commit.
Assisted-by: LLM
Signed-off-by: Shashank Mohan Jain <jain.sm@gmail.com>
---
lib/Kconfig.debug | 15 ++++++
lib/dim/Makefile | 2 +
lib/dim/dim_kunit.c | 126 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 143 insertions(+)
create mode 100644 lib/dim/dim_kunit.c
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 134b15a44625..6b24a2c89b84 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2906,6 +2906,21 @@ config LIVEUPDATE_TEST
If unsure, say N
+config DIMLIB_KUNIT_TEST
+ tristate "KUnit test for the DIM library" if !KUNIT_ALL_TESTS
+ depends on KUNIT && NET
+ select DIMLIB
+ default KUNIT_ALL_TESTS
+ help
+ This builds the KUnit test for the Dynamic Interrupt Moderation
+ library (lib/dim/), which checks the rate statistics computed by
+ dim_calc_stats().
+
+ For more information on KUnit and unit tests in general please refer
+ to the KUnit documentation in Documentation/dev-tools/kunit/.
+
+ If unsure, say N.
+
config CMDLINE_KUNIT_TEST
tristate "KUnit test for cmdline API" if !KUNIT_ALL_TESTS
depends on KUNIT
diff --git a/lib/dim/Makefile b/lib/dim/Makefile
index 5b9bfaac7ac1..47e1c36230e4 100644
--- a/lib/dim/Makefile
+++ b/lib/dim/Makefile
@@ -5,3 +5,5 @@
obj-$(CONFIG_DIMLIB) += dimlib.o
dimlib-y := dim.o net_dim.o rdma_dim.o
+
+obj-$(CONFIG_DIMLIB_KUNIT_TEST) += dim_kunit.o
diff --git a/lib/dim/dim_kunit.c b/lib/dim/dim_kunit.c
new file mode 100644
index 000000000000..2e984f6b9fe4
--- /dev/null
+++ b/lib/dim/dim_kunit.c
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KUnit tests for the Dynamic Interrupt Moderation library
+ */
+
+#include <kunit/test.h>
+#include <linux/dim.h>
+#include <linux/ktime.h>
+#include <linux/module.h>
+
+struct dim_calc_stats_case {
+ const char *name;
+ u32 delta_us;
+ u32 start_pkts, end_pkts;
+ u32 start_bytes, end_bytes;
+ u32 start_comps, end_comps;
+ int ppms, bpms, cpms;
+};
+
+static const struct dim_calc_stats_case dim_calc_stats_cases[] = {
+ {
+ .name = "small",
+ .delta_us = 1000,
+ .end_pkts = 640, .end_bytes = 640 * 1500, .end_comps = 64,
+ .ppms = 640, .bpms = 960000, .cpms = 64,
+ },
+ {
+ .name = "round_up",
+ .delta_us = 3000,
+ .end_pkts = 10, .end_bytes = 10, .end_comps = 1,
+ .ppms = 4, .bpms = 4, .cpms = 1,
+ },
+ {
+ .name = "counter_wrap",
+ .delta_us = 1000,
+ .start_pkts = 0xffffff00, .end_pkts = 0x100,
+ .start_bytes = 0xfffff000, .end_bytes = 0x1000,
+ .start_comps = 0xfffffff0, .end_comps = 0x10,
+ .ppms = 0x200, .bpms = 0x2000, .cpms = 0x20,
+ },
+ {
+ /* 30 MB in 10 ms (24 Gbit/s): nbytes * 1000 exceeds 32 bits */
+ .name = "many_bytes",
+ .delta_us = 10000,
+ .end_pkts = 20000, .end_bytes = 30000000, .end_comps = 64,
+ .ppms = 2000, .bpms = 3000000, .cpms = 7,
+ },
+ {
+ /* 4.3 MB in 16 ms (2.15 Gbit/s), just above the 32-bit limit */
+ .name = "bytes_32bit_limit",
+ .delta_us = 16000,
+ .end_pkts = 2900, .end_bytes = 4300000, .end_comps = 64,
+ .ppms = 182, .bpms = 268750, .cpms = 4,
+ },
+ {
+ /* 5 MB in 40 ms: a 1 Gbit/s link at line rate */
+ .name = "gigabit",
+ .delta_us = 40000,
+ .end_pkts = 3300, .end_bytes = 5000000, .end_comps = 64,
+ .ppms = 83, .bpms = 125000, .cpms = 2,
+ },
+ {
+ /* 5 million packets and completions in 2 s */
+ .name = "many_packets",
+ .delta_us = 2000000,
+ .end_pkts = 5000000, .end_bytes = 5000000, .end_comps = 5000000,
+ .ppms = 2500, .bpms = 2500, .cpms = 2500,
+ },
+};
+
+static void dim_calc_stats_case_desc(const struct dim_calc_stats_case *t,
+ char *desc)
+{
+ strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
+}
+
+KUNIT_ARRAY_PARAM(dim_calc_stats, dim_calc_stats_cases,
+ dim_calc_stats_case_desc);
+
+static void dim_calc_stats_test(struct kunit *test)
+{
+ const struct dim_calc_stats_case *t = test->param_value;
+ struct dim_sample start = {}, end = {};
+ struct dim_stats stats = {};
+
+ dim_update_sample_with_comps(0, t->start_pkts, t->start_bytes,
+ t->start_comps, &start);
+ dim_update_sample_with_comps(DIM_NEVENTS, t->end_pkts, t->end_bytes,
+ t->end_comps, &end);
+ /* dim_update_sample() stamps ktime_get(); use fixed times instead */
+ start.time = ktime_set(1000, 0);
+ end.time = ktime_add_us(start.time, t->delta_us);
+
+ KUNIT_ASSERT_TRUE(test, dim_calc_stats(&start, &end, &stats));
+ KUNIT_EXPECT_EQ(test, stats.ppms, t->ppms);
+ KUNIT_EXPECT_EQ(test, stats.bpms, t->bpms);
+ KUNIT_EXPECT_EQ(test, stats.cpms, t->cpms);
+ KUNIT_EXPECT_EQ(test, stats.epms,
+ (int)DIV_ROUND_UP(DIM_NEVENTS * USEC_PER_MSEC,
+ t->delta_us));
+}
+
+static void dim_calc_stats_no_time_test(struct kunit *test)
+{
+ struct dim_sample sample = {};
+ struct dim_stats stats = {};
+
+ dim_update_sample_with_comps(0, 100, 1000, 10, &sample);
+ KUNIT_EXPECT_FALSE(test, dim_calc_stats(&sample, &sample, &stats));
+}
+
+static struct kunit_case dim_test_cases[] = {
+ KUNIT_CASE_PARAM(dim_calc_stats_test, dim_calc_stats_gen_params),
+ KUNIT_CASE(dim_calc_stats_no_time_test),
+ {}
+};
+
+static struct kunit_suite dim_test_suite = {
+ .name = "dim",
+ .test_cases = dim_test_cases,
+};
+
+kunit_test_suite(dim_test_suite);
+
+MODULE_DESCRIPTION("KUnit tests for the DIM library");
+MODULE_LICENSE("GPL");
--
2.43.0
prev parent reply other threads:[~2026-09-27 5:18 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-27 5:17 [PATCH net 0/2] lib/dim: fix 32-bit overflow in dim_calc_stats() Shashank Mohan Jain
2026-09-27 5:17 ` [PATCH net 1/2] lib/dim: fix 32-bit overflow in dim_calc_stats() rates Shashank Mohan Jain
2026-09-27 5:17 ` Shashank Mohan Jain [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260927051743.71460-3-jain.sm@gmail.com \
--to=jain.sm@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=saeedm@nvidia.com \
--cc=talgi@nvidia.com \
--cc=tariqt@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®