Rust for Linux List
 help / color / mirror / Atom feed
* [PATCH v4 0/7] rust: use Delta instead of raw jiffies for timeouts and delays
@ 2026-07-22 21:49 FUJITA Tomonori
  2026-07-22 21:49 ` [PATCH v4 1/7] rust: time: make Delta generic over its time unit FUJITA Tomonori
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: FUJITA Tomonori @ 2026-07-22 21:49 UTC (permalink / raw)
  To: a.hindborg, aliceryhl, arve, boqun, brauner, cmllamas, gary,
	gregkh, ojeda, tkjos
  Cc: acourbot, anna-maria, bjorn3_gh, dakr, daniel.almeida, frederic,
	jstultz, lossin, lyude, sboyd, tamird, tglx, tmgross, work,
	rust-for-linux, FUJITA Tomonori

From: FUJITA Tomonori <fujita.tomonori@gmail.com>

CondVar::wait_interruptible_timeout() and Queue::enqueue_delayed() use
a raw jiffies count (a plain c_ulong alias with no type
safety). Callers have to know on their own that the value meant
jiffies and convert to/from it themselves, which is easy to get wrong
(e.g. passing a millisecond value where a jiffies value is expected).

Both APIs just take a span of time so, they can use the Delta type
instead.

This series makes Delta generic over its time unit with Nsec and Jiffy
types, switches CondVar and Queue to use Delta instead of raw jiffies
(updating binder's ioctl_freeze(), the only caller of
wait_interruptible_timeout()), and then removes the now-unused Jiffies
and Msecs type aliases.

---
v4:
- Make Delta generic over its time unit with Nsec and Jiffy types
v3: https://lore.kernel.org/rust-for-linux/20260717042247.3634961-1-tomo@flapping.org/
- Add new Jiffies type and convert the APIs to take impl Into<Jiffies>
v2: https://lore.kernel.org/rust-for-linux/20260712235246.3069713-1-tomo@flapping.org/
- Fix potential overflow in from_jiffies()
- Fix inflating bug in as_jiffies_ceil()
- Add a patch to convert enqueue_delayed()
- Add a patch to remove Jiffies/Msecs aliases
v1: https://lore.kernel.org/rust-for-linux/20260704132558.2253275-1-tomo@aliasing.net/

---
FUJITA Tomonori (7):
  rust: time: make Delta generic over its time unit
  rust: time: add jiffies time unit for Delta
  rust: time: add Delta::as_millis_ceil()
  rust: time: add Delta::to_jiffies() for timeout conversion
  rust: workqueue: take a Delta<Jiffy> for the enqueue delay
  rust: sync: condvar: use Delta<Jiffy> for timeout and result
  rust: time: remove unused Jiffies/Msecs helpers

 drivers/android/binder/process.rs |   6 +-
 rust/kernel/sync/condvar.rs       |  29 ++++--
 rust/kernel/time.rs               | 156 ++++++++++++++++++++++--------
 rust/kernel/workqueue.rs          |  12 ++-
 4 files changed, 150 insertions(+), 53 deletions(-)


base-commit: 7059bdf4f04a3e14f4fafb3ac35fdca913e3e21a
-- 
2.43.0


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

* [PATCH v4 1/7] rust: time: make Delta generic over its time unit
  2026-07-22 21:49 [PATCH v4 0/7] rust: use Delta instead of raw jiffies for timeouts and delays FUJITA Tomonori
@ 2026-07-22 21:49 ` FUJITA Tomonori
  2026-07-22 21:49 ` [PATCH v4 2/7] rust: time: add jiffies time unit for Delta FUJITA Tomonori
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: FUJITA Tomonori @ 2026-07-22 21:49 UTC (permalink / raw)
  To: a.hindborg, aliceryhl, arve, boqun, brauner, cmllamas, gary,
	gregkh, ojeda, tkjos
  Cc: acourbot, anna-maria, bjorn3_gh, dakr, daniel.almeida, frederic,
	jstultz, lossin, lyude, sboyd, tamird, tglx, tmgross, work,
	rust-for-linux, FUJITA Tomonori

From: FUJITA Tomonori <fujita.tomonori@gmail.com>

Delta hardcodes its value as i64 nanoseconds. A later patch adds a
jiffies span, whose natural representation is isize jiffies rather than
i64 nanoseconds, and a separate type per unit would duplicate the
arithmetic and comparison machinery.

Make Delta generic over its time unit so the jiffies span can reuse that
machinery. The nanosecond Delta keeps its current representation and API
via the default unit parameter, so no functional change.
users.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
---
 rust/kernel/time.rs | 72 ++++++++++++++++++++++++++++++---------------
 1 file changed, 48 insertions(+), 24 deletions(-)

diff --git a/rust/kernel/time.rs b/rust/kernel/time.rs
index 363e93cbb139..8c01ca62b471 100644
--- a/rust/kernel/time.rs
+++ b/rust/kernel/time.rs
@@ -246,7 +246,7 @@ impl<C: ClockSource> ops::Sub for Instant<C> {
     #[inline]
     fn sub(self, other: Instant<C>) -> Delta {
         Delta {
-            nanos: self.inner - other.inner,
+            value: self.inner - other.inner,
         }
     }
 }
@@ -258,7 +258,7 @@ impl<T: ClockSource> ops::Add<Delta> for Instant<T> {
     fn add(self, rhs: Delta) -> Self::Output {
         // INVARIANT: With arithmetic over/underflow checks enabled, this will panic if we overflow
         // (e.g. go above `KTIME_MAX`)
-        let res = self.inner + rhs.nanos;
+        let res = self.inner + rhs.value;
 
         // INVARIANT: With overflow checks enabled, we verify here that the value is >= 0
         #[cfg(CONFIG_RUST_OVERFLOW_CHECKS)]
@@ -278,7 +278,7 @@ impl<T: ClockSource> ops::Sub<Delta> for Instant<T> {
     fn sub(self, rhs: Delta) -> Self::Output {
         // INVARIANT: With arithmetic over/underflow checks enabled, this will panic if we overflow
         // (e.g. go above `KTIME_MAX`)
-        let res = self.inner - rhs.nanos;
+        let res = self.inner - rhs.value;
 
         // INVARIANT: With overflow checks enabled, we verify here that the value is >= 0
         #[cfg(CONFIG_RUST_OVERFLOW_CHECKS)]
@@ -291,14 +291,38 @@ fn sub(self, rhs: Delta) -> Self::Output {
     }
 }
 
+mod private {
+    pub trait Sealed {}
+
+    impl Sealed for super::Nsec {}
+}
+
+/// A trait for time units.
+pub trait TimeUnit: private::Sealed {
+    /// The underlying representation of the time unit.
+    type Repr: Copy + Clone + PartialEq + PartialOrd + Eq + Ord + core::fmt::Debug;
+}
+
+/// A time unit of nanoseconds.
+///
+/// A [`Delta<Nsec>`] stores its value as `i64` nanoseconds and can represent
+/// any `i64` value, including negative, zero, and positive numbers.
+#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)]
+pub struct Nsec;
+
+impl TimeUnit for Nsec {
+    type Repr = i64;
+}
+
 /// A span of time.
 ///
-/// This struct represents a span of time, with its value stored as nanoseconds.
-/// The value can represent any valid i64 value, including negative, zero, and
-/// positive numbers.
+/// The span is stored in the unit given by the type parameter `U` (see
+/// [`TimeUnit`]); its value has type `U::Repr`. `U` defaults to [`Nsec`], so a
+/// plain [`Delta`] is a span in nanoseconds. The value can be negative, zero, or
+/// positive.
 #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)]
-pub struct Delta {
-    nanos: i64,
+pub struct Delta<U: TimeUnit = Nsec> {
+    value: U::Repr,
 }
 
 impl ops::Add for Delta {
@@ -307,7 +331,7 @@ impl ops::Add for Delta {
     #[inline]
     fn add(self, rhs: Self) -> Self {
         Self {
-            nanos: self.nanos + rhs.nanos,
+            value: self.value + rhs.value,
         }
     }
 }
@@ -315,7 +339,7 @@ fn add(self, rhs: Self) -> Self {
 impl ops::AddAssign for Delta {
     #[inline]
     fn add_assign(&mut self, rhs: Self) {
-        self.nanos += rhs.nanos;
+        self.value += rhs.value;
     }
 }
 
@@ -325,7 +349,7 @@ impl ops::Sub for Delta {
     #[inline]
     fn sub(self, rhs: Self) -> Self::Output {
         Self {
-            nanos: self.nanos - rhs.nanos,
+            value: self.value - rhs.value,
         }
     }
 }
@@ -333,7 +357,7 @@ fn sub(self, rhs: Self) -> Self::Output {
 impl ops::SubAssign for Delta {
     #[inline]
     fn sub_assign(&mut self, rhs: Self) {
-        self.nanos -= rhs.nanos;
+        self.value -= rhs.value;
     }
 }
 
@@ -343,7 +367,7 @@ impl ops::Mul<i64> for Delta {
     #[inline]
     fn mul(self, rhs: i64) -> Self::Output {
         Self {
-            nanos: self.nanos * rhs,
+            value: self.value * rhs,
         }
     }
 }
@@ -351,7 +375,7 @@ fn mul(self, rhs: i64) -> Self::Output {
 impl ops::MulAssign<i64> for Delta {
     #[inline]
     fn mul_assign(&mut self, rhs: i64) {
-        self.nanos *= rhs;
+        self.value *= rhs;
     }
 }
 
@@ -362,25 +386,25 @@ impl ops::Div for Delta {
     fn div(self, rhs: Self) -> Self::Output {
         #[cfg(CONFIG_64BIT)]
         {
-            self.nanos / rhs.nanos
+            self.value / rhs.value
         }
 
         #[cfg(not(CONFIG_64BIT))]
         {
             // SAFETY: This function is always safe to call regardless of the input values
-            unsafe { bindings::div64_s64(self.nanos, rhs.nanos) }
+            unsafe { bindings::div64_s64(self.value, rhs.value) }
         }
     }
 }
 
 impl Delta {
     /// A span of time equal to zero.
-    pub const ZERO: Self = Self { nanos: 0 };
+    pub const ZERO: Self = Self { value: 0 };
 
     /// Create a new [`Delta`] from a number of nanoseconds.
     #[inline]
     pub const fn from_nanos(nanos: i64) -> Self {
-        Self { nanos }
+        Self { value: nanos }
     }
 
     /// Create a new [`Delta`] from a number of microseconds.
@@ -391,7 +415,7 @@ pub const fn from_nanos(nanos: i64) -> Self {
     #[inline]
     pub const fn from_micros(micros: i64) -> Self {
         Self {
-            nanos: micros.saturating_mul(NSEC_PER_USEC),
+            value: micros.saturating_mul(NSEC_PER_USEC),
         }
     }
 
@@ -403,7 +427,7 @@ pub const fn from_micros(micros: i64) -> Self {
     #[inline]
     pub const fn from_millis(millis: i64) -> Self {
         Self {
-            nanos: millis.saturating_mul(NSEC_PER_MSEC),
+            value: millis.saturating_mul(NSEC_PER_MSEC),
         }
     }
 
@@ -415,7 +439,7 @@ pub const fn from_millis(millis: i64) -> Self {
     #[inline]
     pub const fn from_secs(secs: i64) -> Self {
         Self {
-            nanos: secs.saturating_mul(NSEC_PER_SEC),
+            value: secs.saturating_mul(NSEC_PER_SEC),
         }
     }
 
@@ -434,7 +458,7 @@ pub fn is_negative(self) -> bool {
     /// Return the number of nanoseconds in the [`Delta`].
     #[inline]
     pub const fn as_nanos(self) -> i64 {
-        self.nanos
+        self.value
     }
 
     /// Return the smallest number of microseconds greater than or equal
@@ -477,7 +501,7 @@ pub fn rem_nanos(self, dividend: i32) -> Self {
         #[cfg(CONFIG_64BIT)]
         {
             Self {
-                nanos: self.as_nanos() % i64::from(dividend),
+                value: self.as_nanos() % i64::from(dividend),
             }
         }
 
@@ -489,7 +513,7 @@ pub fn rem_nanos(self, dividend: i32) -> Self {
             unsafe { bindings::div_s64_rem(self.as_nanos(), dividend, &mut rem) };
 
             Self {
-                nanos: i64::from(rem),
+                value: i64::from(rem),
             }
         }
     }
-- 
2.43.0


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

* [PATCH v4 2/7] rust: time: add jiffies time unit for Delta
  2026-07-22 21:49 [PATCH v4 0/7] rust: use Delta instead of raw jiffies for timeouts and delays FUJITA Tomonori
  2026-07-22 21:49 ` [PATCH v4 1/7] rust: time: make Delta generic over its time unit FUJITA Tomonori
@ 2026-07-22 21:49 ` FUJITA Tomonori
  2026-07-22 21:49 ` [PATCH v4 3/7] rust: time: add Delta::as_millis_ceil() FUJITA Tomonori
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: FUJITA Tomonori @ 2026-07-22 21:49 UTC (permalink / raw)
  To: a.hindborg, aliceryhl, arve, boqun, brauner, cmllamas, gary,
	gregkh, ojeda, tkjos
  Cc: acourbot, anna-maria, bjorn3_gh, dakr, daniel.almeida, frederic,
	jstultz, lossin, lyude, sboyd, tamird, tglx, tmgross, work,
	rust-for-linux, FUJITA Tomonori

From: FUJITA Tomonori <fujita.tomonori@gmail.com>

Add a Jiffy time unit with isize as its representation and provide
Delta<Jiffy>::from_jiffies() and as_jiffies() as the unit-specific
constructor and accessor, mirroring from_nanos()/as_nanos() on the
nanosecond Delta.

Represent the jiffies span as isize: Delta is a signed span (nanoseconds
use i64) and, as a timeout, the value only needs to reach
MAX_JIFFY_OFFSET ((LONG_MAX >> 1) - 1). isize is signed and matches the
kernel's c_long, so it meets both.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
---
 rust/kernel/time.rs | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/rust/kernel/time.rs b/rust/kernel/time.rs
index 8c01ca62b471..20f059d19a6c 100644
--- a/rust/kernel/time.rs
+++ b/rust/kernel/time.rs
@@ -295,6 +295,7 @@ mod private {
     pub trait Sealed {}
 
     impl Sealed for super::Nsec {}
+    impl Sealed for super::Jiffy {}
 }
 
 /// A trait for time units.
@@ -314,6 +315,17 @@ impl TimeUnit for Nsec {
     type Repr = i64;
 }
 
+/// A time unit of jiffies.
+///
+/// A [`Delta<Jiffy>`] stores its value as `isize` jiffies and can represent
+/// any `isize` value, including negative, zero, and positive numbers.
+#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)]
+pub struct Jiffy;
+
+impl TimeUnit for Jiffy {
+    type Repr = isize;
+}
+
 /// A span of time.
 ///
 /// The span is stored in the unit given by the type parameter `U` (see
@@ -325,6 +337,20 @@ pub struct Delta<U: TimeUnit = Nsec> {
     value: U::Repr,
 }
 
+impl Delta<Jiffy> {
+    /// Create a new [`Delta`] from a number of jiffies.
+    #[inline]
+    pub const fn from_jiffies(jiffies: isize) -> Self {
+        Self { value: jiffies }
+    }
+
+    /// Return the number of jiffies in the [`Delta`].
+    #[inline]
+    pub const fn as_jiffies(self) -> isize {
+        self.value
+    }
+}
+
 impl ops::Add for Delta {
     type Output = Self;
 
-- 
2.43.0


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

* [PATCH v4 3/7] rust: time: add Delta::as_millis_ceil()
  2026-07-22 21:49 [PATCH v4 0/7] rust: use Delta instead of raw jiffies for timeouts and delays FUJITA Tomonori
  2026-07-22 21:49 ` [PATCH v4 1/7] rust: time: make Delta generic over its time unit FUJITA Tomonori
  2026-07-22 21:49 ` [PATCH v4 2/7] rust: time: add jiffies time unit for Delta FUJITA Tomonori
@ 2026-07-22 21:49 ` FUJITA Tomonori
  2026-07-22 21:49 ` [PATCH v4 4/7] rust: time: add Delta::to_jiffies() for timeout conversion FUJITA Tomonori
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: FUJITA Tomonori @ 2026-07-22 21:49 UTC (permalink / raw)
  To: a.hindborg, aliceryhl, arve, boqun, brauner, cmllamas, gary,
	gregkh, ojeda, tkjos
  Cc: acourbot, anna-maria, bjorn3_gh, dakr, daniel.almeida, frederic,
	jstultz, lossin, lyude, sboyd, tamird, tglx, tmgross, work,
	rust-for-linux, FUJITA Tomonori

From: FUJITA Tomonori <fujita.tomonori@gmail.com>

Add a ceiling variant, mirroring the existing as_micros_ceil() since
the existing as_millis() truncates towards zero.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
---
 rust/kernel/time.rs | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/rust/kernel/time.rs b/rust/kernel/time.rs
index 20f059d19a6c..f890c2d03932 100644
--- a/rust/kernel/time.rs
+++ b/rust/kernel/time.rs
@@ -518,6 +518,29 @@ pub fn as_millis(self) -> i64 {
         }
     }
 
+    /// Return the smallest number of milliseconds greater than or equal
+    /// to the value in the [`Delta`].
+    #[inline]
+    pub fn as_millis_ceil(self) -> i64 {
+        let n = self.as_nanos();
+        let n = if n > 0 {
+            n.saturating_add(NSEC_PER_MSEC - 1)
+        } else {
+            n
+        };
+
+        #[cfg(CONFIG_64BIT)]
+        {
+            n / NSEC_PER_MSEC
+        }
+
+        #[cfg(not(CONFIG_64BIT))]
+        // SAFETY: It is always safe to call `ktime_to_ms()` with any value.
+        unsafe {
+            bindings::ktime_to_ms(n)
+        }
+    }
+
     /// Return `self % dividend` where `dividend` is in nanoseconds.
     ///
     /// The kernel doesn't have any emulation for `s64 % s64` on 32 bit platforms, so this is
-- 
2.43.0


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

* [PATCH v4 4/7] rust: time: add Delta::to_jiffies() for timeout conversion
  2026-07-22 21:49 [PATCH v4 0/7] rust: use Delta instead of raw jiffies for timeouts and delays FUJITA Tomonori
                   ` (2 preceding siblings ...)
  2026-07-22 21:49 ` [PATCH v4 3/7] rust: time: add Delta::as_millis_ceil() FUJITA Tomonori
@ 2026-07-22 21:49 ` FUJITA Tomonori
  2026-07-22 21:49 ` [PATCH v4 5/7] rust: workqueue: take a Delta<Jiffy> for the enqueue delay FUJITA Tomonori
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: FUJITA Tomonori @ 2026-07-22 21:49 UTC (permalink / raw)
  To: a.hindborg, aliceryhl, arve, boqun, brauner, cmllamas, gary,
	gregkh, ojeda, tkjos
  Cc: acourbot, anna-maria, bjorn3_gh, dakr, daniel.almeida, frederic,
	jstultz, lossin, lyude, sboyd, tamird, tglx, tmgross, work,
	rust-for-linux, FUJITA Tomonori

From: FUJITA Tomonori <fujita.tomonori@gmail.com>

Add Delta<Nsec>::to_jiffies() conversion that rounds up so the
resulting timeout is never shorter than the requested span, clamps a
negative span to an immediate timeout, and saturates an overlong span
to the kernel's MAX_JIFFY_OFFSET "wait forever" value.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
---
 rust/kernel/time.rs | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/rust/kernel/time.rs b/rust/kernel/time.rs
index f890c2d03932..900481a3cba2 100644
--- a/rust/kernel/time.rs
+++ b/rust/kernel/time.rs
@@ -541,6 +541,27 @@ pub fn as_millis_ceil(self) -> i64 {
         }
     }
 
+    /// Convert this span to a [`Delta<Jiffy>`] suitable for use as a timeout.
+    ///
+    /// The value is rounded up to the next whole jiffy, so the resulting
+    /// timeout is never shorter than `self` (as `msecs_to_jiffies()` does).
+    /// A negative span clamps to zero jiffies (an immediate timeout).
+    #[inline]
+    pub fn to_jiffies(self) -> Delta<Jiffy> {
+        let msecs = self.as_millis_ceil();
+
+        // CAST: `msecs` is clamped to `0..=c_uint::MAX`, so it is non-negative and
+        // fits in `c_uint`.
+        let msecs = msecs.clamp(0, i64::from(crate::ffi::c_uint::MAX)) as crate::ffi::c_uint;
+
+        // SAFETY: `__msecs_to_jiffies()` is always safe to call.
+        let jiffies = unsafe { bindings::__msecs_to_jiffies(msecs) };
+
+        // CAST: `__msecs_to_jiffies()` returns a value in `0..=MAX_JIFFY_OFFSET`, i.e.
+        // `((LONG_MAX >> 1) - 1)`, which is non-negative and well within `isize`.
+        Delta::<Jiffy>::from_jiffies(jiffies as isize)
+    }
+
     /// Return `self % dividend` where `dividend` is in nanoseconds.
     ///
     /// The kernel doesn't have any emulation for `s64 % s64` on 32 bit platforms, so this is
-- 
2.43.0


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

* [PATCH v4 5/7] rust: workqueue: take a Delta<Jiffy> for the enqueue delay
  2026-07-22 21:49 [PATCH v4 0/7] rust: use Delta instead of raw jiffies for timeouts and delays FUJITA Tomonori
                   ` (3 preceding siblings ...)
  2026-07-22 21:49 ` [PATCH v4 4/7] rust: time: add Delta::to_jiffies() for timeout conversion FUJITA Tomonori
@ 2026-07-22 21:49 ` FUJITA Tomonori
  2026-07-22 21:49 ` [PATCH v4 6/7] rust: sync: condvar: use Delta<Jiffy> for timeout and result FUJITA Tomonori
  2026-07-22 21:49 ` [PATCH v4 7/7] rust: time: remove unused Jiffies/Msecs helpers FUJITA Tomonori
  6 siblings, 0 replies; 8+ messages in thread
From: FUJITA Tomonori @ 2026-07-22 21:49 UTC (permalink / raw)
  To: a.hindborg, aliceryhl, arve, boqun, brauner, cmllamas, gary,
	gregkh, ojeda, tkjos
  Cc: acourbot, anna-maria, bjorn3_gh, dakr, daniel.almeida, frederic,
	jstultz, lossin, lyude, sboyd, tamird, tglx, tmgross, work,
	rust-for-linux, FUJITA Tomonori

From: FUJITA Tomonori <fujita.tomonori@gmail.com>

enqueue_delayed() takes the delay as a raw Jiffies (c_ulong). That is
the C representation rather than a kernel time type, so it neither
carries the unit in its type nor composes with the Delta arithmetic
used elsewhere for expressing spans, and it forces callers to hand the
API a bare integer.

Change the delay parameter to Delta<Jiffy> so a delay is expressed in
the same time vocabulary as the rest of the kernel crate. A signed
Delta can be negative, so clamp it to zero before handing it to the C
side, which keeps "no delay" the natural meaning of a non-positive
span.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
---
 rust/kernel/workqueue.rs | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs
index 7e253b6f299c..d4f8a3ea5acb 100644
--- a/rust/kernel/workqueue.rs
+++ b/rust/kernel/workqueue.rs
@@ -171,7 +171,7 @@
 //! /// This method will enqueue the struct for execution on the system workqueue, where its value
 //! /// will be printed 12 jiffies later.
 //! fn print_later(val: Arc<MyStruct>) {
-//!     let _ = workqueue::system().enqueue_delayed(val, 12);
+//!     let _ = workqueue::system().enqueue_delayed(val, kernel::time::Delta::from_jiffies(12));
 //! }
 //!
 //! /// It is also possible to use the ordinary `enqueue` method together with `DelayedWork`. This
@@ -197,7 +197,10 @@
         Arc,
         LockClassKey, //
     },
-    time::Jiffies,
+    time::{
+        Delta,
+        Jiffy, //
+    },
     types::Opaque,
 };
 use core::{marker::PhantomData, ptr::NonNull};
@@ -303,11 +306,14 @@ pub fn enqueue<W, const ID: u64>(&self, w: W) -> W::EnqueueOutput
     /// This may fail if the work item is already enqueued in a workqueue.
     ///
     /// The work item will be submitted using `WORK_CPU_UNBOUND`.
-    pub fn enqueue_delayed<W, const ID: u64>(&self, w: W, delay: Jiffies) -> W::EnqueueOutput
+    pub fn enqueue_delayed<W, const ID: u64>(&self, w: W, delta: Delta<Jiffy>) -> W::EnqueueOutput
     where
         W: RawDelayedWorkItem<ID> + Send + 'static,
     {
         let queue_ptr = self.0.get();
+        // CAST: A negative delay is clamped to `0`, so the value is non-negative
+        // and fits in `c_ulong`.
+        let delay = delta.as_jiffies().max(0) as ffi::c_ulong;
 
         // SAFETY: We only return `false` if the `work_struct` is already in a workqueue. The other
         // `__enqueue` requirements are not relevant since `W` is `Send` and static.
-- 
2.43.0


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

* [PATCH v4 6/7] rust: sync: condvar: use Delta<Jiffy> for timeout and result
  2026-07-22 21:49 [PATCH v4 0/7] rust: use Delta instead of raw jiffies for timeouts and delays FUJITA Tomonori
                   ` (4 preceding siblings ...)
  2026-07-22 21:49 ` [PATCH v4 5/7] rust: workqueue: take a Delta<Jiffy> for the enqueue delay FUJITA Tomonori
@ 2026-07-22 21:49 ` FUJITA Tomonori
  2026-07-22 21:49 ` [PATCH v4 7/7] rust: time: remove unused Jiffies/Msecs helpers FUJITA Tomonori
  6 siblings, 0 replies; 8+ messages in thread
From: FUJITA Tomonori @ 2026-07-22 21:49 UTC (permalink / raw)
  To: a.hindborg, aliceryhl, arve, boqun, brauner, cmllamas, gary,
	gregkh, ojeda, tkjos
  Cc: acourbot, anna-maria, bjorn3_gh, dakr, daniel.almeida, frederic,
	jstultz, lossin, lyude, sboyd, tamird, tglx, tmgross, work,
	rust-for-linux, FUJITA Tomonori

From: FUJITA Tomonori <fujita.tomonori@gmail.com>

wait_interruptible_timeout() takes the timeout as a raw Jiffies and
reports the remaining time as raw Jiffies in CondVarTimeoutResult. That
is the C representation rather than a kernel time type, so it neither
carries the unit in its type nor composes with the Delta spans used
elsewhere, and it pushes the unsigned-to-signed conversion onto callers.

Switch the parameter and the result fields to Delta<Jiffy>. So a delay
is expressed in the same time vocabulary as the rest of the kernel
crate.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
---
 drivers/android/binder/process.rs |  6 +++---
 rust/kernel/sync/condvar.rs       | 29 ++++++++++++++++++++---------
 2 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/drivers/android/binder/process.rs b/drivers/android/binder/process.rs
index cdd1a9079726..314962b5361d 100644
--- a/drivers/android/binder/process.rs
+++ b/drivers/android/binder/process.rs
@@ -1482,8 +1482,8 @@ pub(crate) fn ioctl_freeze(&self, info: &BinderFreezeInfo) -> Result {
         inner.is_frozen = IsFrozen::InProgress;
 
         if info.timeout_ms > 0 {
-            let mut jiffies = kernel::time::msecs_to_jiffies(info.timeout_ms);
-            while jiffies > 0 {
+            let mut jiffies = kernel::time::Delta::from_millis(info.timeout_ms.into()).to_jiffies();
+            while jiffies.as_jiffies() > 0 {
                 if inner.outstanding_txns == 0 {
                     break;
                 }
@@ -1500,7 +1500,7 @@ pub(crate) fn ioctl_freeze(&self, info: &BinderFreezeInfo) -> Result {
                         jiffies = remaining;
                     }
                     CondVarTimeoutResult::Timeout => {
-                        jiffies = 0;
+                        jiffies = kernel::time::Delta::from_jiffies(0);
                     }
                 }
             }
diff --git a/rust/kernel/sync/condvar.rs b/rust/kernel/sync/condvar.rs
index 69d58dfbad7b..73e123aac860 100644
--- a/rust/kernel/sync/condvar.rs
+++ b/rust/kernel/sync/condvar.rs
@@ -12,7 +12,10 @@
     task::{
         MAX_SCHEDULE_TIMEOUT, TASK_FREEZABLE, TASK_INTERRUPTIBLE, TASK_NORMAL, TASK_UNINTERRUPTIBLE,
     },
-    time::Jiffies,
+    time::{
+        Delta,
+        Jiffy, //
+    },
     types::Opaque,
 };
 use core::{marker::PhantomPinned, pin::Pin, ptr};
@@ -186,15 +189,23 @@ pub fn wait_interruptible_freezable<T: ?Sized, B: Backend>(
     pub fn wait_interruptible_timeout<T: ?Sized, B: Backend>(
         &self,
         guard: &mut Guard<'_, T, B>,
-        jiffies: Jiffies,
+        delta: Delta<Jiffy>,
     ) -> CondVarTimeoutResult {
-        let jiffies = jiffies.try_into().unwrap_or(MAX_SCHEDULE_TIMEOUT);
-        let res = self.wait_internal(TASK_INTERRUPTIBLE, guard, jiffies);
+        let jiffies = delta.as_jiffies();
+        let res = self.wait_internal(
+            TASK_INTERRUPTIBLE,
+            guard,
+            jiffies.clamp(0, MAX_SCHEDULE_TIMEOUT),
+        );
 
-        match (res as Jiffies, crate::current!().signal_pending()) {
-            (jiffies, true) => CondVarTimeoutResult::Signal { jiffies },
+        match (res, crate::current!().signal_pending()) {
+            (jiffies, true) => CondVarTimeoutResult::Signal {
+                jiffies: Delta::from_jiffies(jiffies),
+            },
             (0, false) => CondVarTimeoutResult::Timeout,
-            (jiffies, false) => CondVarTimeoutResult::Woken { jiffies },
+            (jiffies, false) => CondVarTimeoutResult::Woken {
+                jiffies: Delta::from_jiffies(jiffies),
+            },
         }
     }
 
@@ -248,11 +259,11 @@ pub enum CondVarTimeoutResult {
     /// Somebody woke us up.
     Woken {
         /// Remaining sleep duration.
-        jiffies: Jiffies,
+        jiffies: Delta<Jiffy>,
     },
     /// A signal occurred.
     Signal {
         /// Remaining sleep duration.
-        jiffies: Jiffies,
+        jiffies: Delta<Jiffy>,
     },
 }
-- 
2.43.0


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

* [PATCH v4 7/7] rust: time: remove unused Jiffies/Msecs helpers
  2026-07-22 21:49 [PATCH v4 0/7] rust: use Delta instead of raw jiffies for timeouts and delays FUJITA Tomonori
                   ` (5 preceding siblings ...)
  2026-07-22 21:49 ` [PATCH v4 6/7] rust: sync: condvar: use Delta<Jiffy> for timeout and result FUJITA Tomonori
@ 2026-07-22 21:49 ` FUJITA Tomonori
  6 siblings, 0 replies; 8+ messages in thread
From: FUJITA Tomonori @ 2026-07-22 21:49 UTC (permalink / raw)
  To: a.hindborg, aliceryhl, arve, boqun, brauner, cmllamas, gary,
	gregkh, ojeda, tkjos
  Cc: acourbot, anna-maria, bjorn3_gh, dakr, daniel.almeida, frederic,
	jstultz, lossin, lyude, sboyd, tamird, tglx, tmgross, work,
	rust-for-linux, FUJITA Tomonori

From: FUJITA Tomonori <fujita.tomonori@gmail.com>

CondVar's wait_interruptible_timeout() and workqueue's
enqueue_delayed() have both moved from raw jiffies counts to Delta, so
nothing in the tree calls msecs_to_jiffies() or uses the Jiffies and
Msecs aliases anymore.

Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
---
 rust/kernel/time.rs | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/rust/kernel/time.rs b/rust/kernel/time.rs
index 900481a3cba2..876897103a5c 100644
--- a/rust/kernel/time.rs
+++ b/rust/kernel/time.rs
@@ -39,20 +39,6 @@
 /// The number of nanoseconds per second.
 pub const NSEC_PER_SEC: i64 = bindings::NSEC_PER_SEC as i64;
 
-/// The time unit of Linux kernel. One jiffy equals (1/HZ) second.
-pub type Jiffies = crate::ffi::c_ulong;
-
-/// The millisecond time unit.
-pub type Msecs = crate::ffi::c_uint;
-
-/// Converts milliseconds to jiffies.
-#[inline]
-pub fn msecs_to_jiffies(msecs: Msecs) -> Jiffies {
-    // SAFETY: The `__msecs_to_jiffies` function is always safe to call no
-    // matter what the argument is.
-    unsafe { bindings::__msecs_to_jiffies(msecs) }
-}
-
 /// Trait for clock sources.
 ///
 /// Selection of the clock source depends on the use case. In some cases the usage of a
-- 
2.43.0


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

end of thread, other threads:[~2026-07-22 21:52 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-22 21:49 [PATCH v4 0/7] rust: use Delta instead of raw jiffies for timeouts and delays FUJITA Tomonori
2026-07-22 21:49 ` [PATCH v4 1/7] rust: time: make Delta generic over its time unit FUJITA Tomonori
2026-07-22 21:49 ` [PATCH v4 2/7] rust: time: add jiffies time unit for Delta FUJITA Tomonori
2026-07-22 21:49 ` [PATCH v4 3/7] rust: time: add Delta::as_millis_ceil() FUJITA Tomonori
2026-07-22 21:49 ` [PATCH v4 4/7] rust: time: add Delta::to_jiffies() for timeout conversion FUJITA Tomonori
2026-07-22 21:49 ` [PATCH v4 5/7] rust: workqueue: take a Delta<Jiffy> for the enqueue delay FUJITA Tomonori
2026-07-22 21:49 ` [PATCH v4 6/7] rust: sync: condvar: use Delta<Jiffy> for timeout and result FUJITA Tomonori
2026-07-22 21:49 ` [PATCH v4 7/7] rust: time: remove unused Jiffies/Msecs helpers FUJITA Tomonori

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox