mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/3] time/jiffies: Fix usecs_to_jiffies() saturation and jiffies_to_clock_t() rounding
@ 2026-09-28  9:35 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
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Shashank Mohan Jain @ 2026-09-28  9:35 UTC (permalink / raw)
  To: John Stultz, Thomas Gleixner
  Cc: Stephen Boyd, Miroslav Lichvar, Eric Dumazet, Joel Granados,
	linux-kernel

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


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-09-28 12:09 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 3/3] time/kunit: Add tests for usecs_to_jiffies() and jiffies_to_clock_t() Shashank Mohan Jain

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®