From: Shashank Mohan Jain <jain.sm@gmail.com>
To: John Stultz <jstultz@google.com>, Thomas Gleixner <tglx@kernel.org>
Cc: Stephen Boyd <sboyd@kernel.org>,
Miroslav Lichvar <mlichvar@redhat.com>,
Eric Dumazet <edumazet@google.com>,
Joel Granados <joel.granados@kernel.org>,
linux-kernel@vger.kernel.org
Subject: [PATCH 3/3] time/kunit: Add tests for usecs_to_jiffies() and jiffies_to_clock_t()
Date: Mon, 28 Sep 2026 15:06:01 +0530 [thread overview]
Message-ID: <20260928093601.79224-4-jain.sm@gmail.com> (raw)
In-Reply-To: <20260928093601.79224-1-jain.sm@gmail.com>
Check that jiffies_to_clock_t() and jiffies_64_to_clock_t() invert
clock_t_to_jiffies() for every clock_t value that is a whole number of
jiffies, and that usecs_to_jiffies() rounds up and never saturates for
any unsigned int input, both through the out-of-line and the
constant-folded path.
The tests do not depend on HZ. With HZ=100 (UML) the usecs_to_jiffies()
test fails without the preceding fix for the values close to UINT_MAX,
and with HZ=300 both tests fail without the preceding fixes. Each loop
stops at its first failure, so a failing run reports a handful of
values instead of thousands.
Assisted-by: LLM
Signed-off-by: Shashank Mohan Jain <jain.sm@gmail.com>
---
Run with kunit.py, filter "time_test_cases.*jiffies*", with and without
patches 1-2, on UML x86_64 (HZ=100) and on qemu x86_64 and i386 (TCG)
with CONFIG_HZ_300=y. Also on UML x86_64 with HZ/USER_HZ temporarily
edited: with patches 1-2 both tests pass at 24/100, 1024/100, 1200/100,
32/1024, 1024/1024 and 1200/1024; without them both fail at 1200/100
and 1024/1024.
Without the fixes, the HZ=300 x86_64 run now reports 15 failed
expectations (4 KB of output) instead of about 2,900. Prepared with
Claude Code (Anthropic), model Claude Opus 5.5 (claude-opus-5-5).
kernel/time/time_test.c | 79 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 79 insertions(+)
diff --git a/kernel/time/time_test.c b/kernel/time/time_test.c
index 1b99180da288..77e1ec1d5d8b 100644
--- a/kernel/time/time_test.c
+++ b/kernel/time/time_test.c
@@ -1,6 +1,9 @@
// SPDX-License-Identifier: LGPL-2.1+
#include <kunit/test.h>
+#include <linux/gcd.h>
+#include <linux/jiffies.h>
+#include <linux/math64.h>
#include <linux/time.h>
/*
@@ -87,8 +90,84 @@ static void time64_to_tm_test_date_range(struct kunit *test)
}
}
+/*
+ * jiffies_to_clock_t() must be the inverse of clock_t_to_jiffies() for every
+ * clock_t value that is a whole number of jiffies, whatever HZ is.
+ */
+static void jiffies_to_clock_t_test(struct kunit *test)
+{
+ unsigned long step = USER_HZ / gcd(HZ, USER_HZ);
+ unsigned long x;
+
+ /* Bridge STP defaults, exposed in USER_HZ through sysfs and netlink */
+ KUNIT_EXPECT_EQ(test, 15 * USER_HZ, jiffies_to_clock_t(15 * HZ));
+ KUNIT_EXPECT_EQ(test, 2 * USER_HZ, jiffies_to_clock_t(2 * HZ));
+ KUNIT_EXPECT_EQ(test, 300 * USER_HZ, jiffies_to_clock_t(300 * HZ));
+ /* Large enough to catch a rounded NSEC_PER_SEC / USER_HZ (alpha) */
+ KUNIT_EXPECT_EQ(test, 10000 * USER_HZ, jiffies_to_clock_t(10000 * HZ));
+
+ for (x = 0; x <= 100 * USER_HZ; x += step) {
+ unsigned long j = clock_t_to_jiffies(x);
+ clock_t c = jiffies_to_clock_t(j);
+ u64 c64 = jiffies_64_to_clock_t(j);
+
+ KUNIT_ASSERT_EQ_MSG(test, x * HZ, (u64)j * USER_HZ,
+ "clock_t %lu -> %lu jiffies", x, j);
+ if (c != (long)x || c64 != x) {
+ KUNIT_FAIL(test, "clock_t %lu -> %lu jiffies -> %ld / %llu",
+ x, j, (long)c, c64);
+ break;
+ }
+ }
+}
+
+/*
+ * Every unsigned int number of microseconds fits in MAX_JIFFY_OFFSET jiffies
+ * for any supported HZ, so usecs_to_jiffies() must never saturate. It must
+ * round up; when HZ does not divide USEC_PER_SEC, the reciprocal
+ * multiplication may round up by one more jiffy for large values.
+ */
+static bool check_usecs_to_jiffies(struct kunit *test, unsigned int u,
+ unsigned long got)
+{
+ unsigned long want = DIV_ROUND_UP_ULL((u64)u * HZ, USEC_PER_SEC);
+
+ if (got >= want && got <= want + !!(USEC_PER_SEC % HZ))
+ return true;
+ KUNIT_FAIL(test, "usecs_to_jiffies(%u) = %lu, want %lu%s", u, got,
+ want, USEC_PER_SEC % HZ ? " or one more" : "");
+ return false;
+}
+
+static void usecs_to_jiffies_test(struct kunit *test)
+{
+ static const unsigned int vals[] = {
+ 0, 1, 999, 1000, 1001, 1000000, 1431649098, 1431649099,
+ 2000000000, 3000000000U, UINT_MAX - 20000, UINT_MAX - 1,
+ UINT_MAX,
+ };
+ u64 x;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(vals); i++)
+ check_usecs_to_jiffies(test, vals[i], usecs_to_jiffies(vals[i]));
+
+ for (x = 0; x <= UINT_MAX; x += 999983)
+ if (!check_usecs_to_jiffies(test, x, usecs_to_jiffies(x)))
+ break;
+ for (x = UINT_MAX - 30000; x <= UINT_MAX; x++)
+ if (!check_usecs_to_jiffies(test, x, usecs_to_jiffies(x)))
+ break;
+
+ /* Constant-folded variant */
+ check_usecs_to_jiffies(test, 3000000000U, usecs_to_jiffies(3000000000U));
+ check_usecs_to_jiffies(test, UINT_MAX, usecs_to_jiffies(UINT_MAX));
+}
+
static struct kunit_case time_test_cases[] = {
KUNIT_CASE_SLOW(time64_to_tm_test_date_range),
+ KUNIT_CASE(jiffies_to_clock_t_test),
+ KUNIT_CASE(usecs_to_jiffies_test),
{}
};
--
2.43.0
prev parent reply other threads:[~2026-09-28 9:36 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-28 9:35 [PATCH 0/3] time/jiffies: Fix usecs_to_jiffies() saturation and jiffies_to_clock_t() rounding Shashank Mohan Jain
2026-09-28 9:35 ` [PATCH 1/3] time/jiffies: Don't saturate usecs_to_jiffies() on a truncated limit Shashank Mohan Jain
2026-09-28 11:38 ` Joel Granados
2026-09-28 12:09 ` shashank Jain
2026-09-28 9:36 ` [PATCH 2/3] time/jiffies: Use the exact HZ ratio in jiffies_to_clock_t() Shashank Mohan Jain
2026-09-28 9:36 ` 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=20260928093601.79224-4-jain.sm@gmail.com \
--to=jain.sm@gmail.com \
--cc=edumazet@google.com \
--cc=joel.granados@kernel.org \
--cc=jstultz@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mlichvar@redhat.com \
--cc=sboyd@kernel.org \
--cc=tglx@kernel.org \
/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®