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 0/3] time/jiffies: Fix usecs_to_jiffies() saturation and jiffies_to_clock_t() rounding
Date: Mon, 28 Sep 2026 15:05:58 +0530 [thread overview]
Message-ID: <20260928093601.79224-1-jain.sm@gmail.com> (raw)
Two conversion helpers give wrong results for some HZ values:
1) usecs_to_jiffies() compares its input with jiffies_to_usecs(
MAX_JIFFY_OFFSET), which is truncated to 32 bits. With HZ=300 every
timeout from about 23.9 to 71.6 minutes becomes MAX_JIFFY_OFFSET
(infinite); with HZ=100/250/1000 the top few thousand u32 values do.
No u32 number of microseconds can reach MAX_JIFFY_OFFSET, so the
check is dropped (and a u32 wrap it was masking is fixed). As a side
effect, usecs_to_jiffies(<constant>) now folds to a constant when HZ
does not divide USEC_PER_SEC, instead of calling jiffies_to_usecs().
2) jiffies_to_clock_t() and jiffies_64_to_clock_t() use the rounded
TICK_NSEC when HZ does not divide NSEC_PER_SEC, so with HZ=300
jiffies_to_clock_t(300) is 99 and values written in USER_HZ do not
read back (bridge forward_delay reads 1499, neigh locktime reads 99).
They now use the nominal HZ ratio, like clock_t_to_jiffies(). This
also fixes the conversion on alpha (USER_HZ=1024) for large values.
Patch 3 adds HZ-independent KUnit tests for both to
kernel/time/time_test.c.
Testing:
- KUnit, filter "time_test_cases.*jiffies*", on master plus patch 3
and on the whole series: UML x86_64 (HZ=100), and qemu x86_64 and
i386 (TCG) with CONFIG_HZ_300=y. Without the fixes the usecs test
fails on all three and the clock_t test fails on both HZ=300 runs;
with them both tests pass everywhere. On UML x86_64 with HZ/USER_HZ
temporarily edited, the series passes at 24/100, 1024/100, 1200/100,
32/1024, 1024/1024 and 1200/1024, and master plus patch 3 fails both
tests at 1200/100 and 1024/1024.
- A userspace harness that extracts the conversion code verbatim from
the tree, both master and this series, and builds it with the
generated timeconst.h for every Kconfig HZ value (24, 32, 48, 64,
100, 128, 200, 250, 256, 300, 500, 1000, 1024 and 1200), USER_HZ 100
and 1024, 32- and 64-bit. On master it shows both problems. With the
series, usecs_to_jiffies() over all 2^32 inputs never saturates, is
never below the exact rounded-up value and is at most one jiffy above
it (only where HZ does not divide USEC_PER_SEC, as before).
jiffies_to_clock_t() and jiffies_64_to_clock_t() equal
floor(x * USER_HZ / HZ) for every x below 5e7 and invert
clock_t_to_jiffies() for every clock_t value below 2e7 that is a
whole number of jiffies. An earlier harness, with the fixed
expressions retyped rather than extracted, also checked
jiffies_to_clock_t() for every x below 4e8 with USER_HZ=100.
- An x86_64 defconfig kernel with HZ=300 and CONFIG_BRIDGE=y booted in
qemu, with a small init that creates a bridge and reads the values
back. On master: forward_delay 1499, hello_time 199, max_age 1999,
ageing_time 29999, ipv4 neigh retrans_time/anycast_delay/locktime 99,
proxy_delay 79, ipv6 neigh anycast_delay 99, and writing 1500 to
forward_delay and then writing back what was read gives 1499, 1498,
1497; writing 100 to ipv4 locktime reads back 99. With the series:
1500, 200, 2000, 30000, 100, 80, 100, 1500 each time, and 100. ipv6
neigh retrans_time reads 300 on both, as expected (raw jiffies).
- W=1 builds of kernel/time/{time,time_test,jiffies,timer}.o,
net/bridge/{br_sysfs_br,br_netlink}.o and net/core/neighbour.o for
x86_64 and i386 defconfig at HZ=300 and HZ=1000: no warnings before
or after, and no libgcc 64-bit division helpers in time.o on i386.
- checkpatch --strict: clean once the Signed-off-by is added (checked
with one appended).
Not tested: real hardware, and architectures other than x86 (alpha's
USER_HZ=1024 only through the edited UML builds and the harness).
jiffies_to_msecs() on 32-bit also rounds exact values up by one for
HZ=300 (jiffies_to_msecs(3) == 11); that is left for a separate patch.
The series does not overlap with "time/jiffies: Saturate in mult_hz()
instead of wrapping", which is also under review and touches
kernel/time/jiffies.c.
This series was prepared with Claude Code (Anthropic), model Claude
Opus 5.5 (claude-opus-5-5), which found the bugs with the harness above
and a Lean 4 model of the arithmetic, and wrote the patches and tests.
A separate Claude Code session reviewed the series independently, and
the changelogs and tests were revised after that review.
Shashank Mohan Jain (3):
time/jiffies: Don't saturate usecs_to_jiffies() on a truncated limit
time/jiffies: Use the exact HZ ratio in jiffies_to_clock_t()
time/kunit: Add tests for usecs_to_jiffies() and jiffies_to_clock_t()
include/linux/jiffies.h | 22 +++++-------
kernel/time/time.c | 24 +++++++------
kernel/time/time_test.c | 79 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 101 insertions(+), 24 deletions(-)
--
2.43.0
next 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 Shashank Mohan Jain [this message]
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 ` [PATCH 3/3] time/kunit: Add tests for usecs_to_jiffies() and jiffies_to_clock_t() Shashank Mohan Jain
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-1-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®