summaryrefslogtreecommitdiff
path: root/rust
diff options
context:
space:
mode:
authorMiguel Ojeda <ojeda@kernel.org>2026-10-11 18:57:10 +0200
committerMiguel Ojeda <ojeda@kernel.org>2026-10-11 19:23:24 +0200
commit0d6d7ab3d4f42b840dfa6057b9c7026d2b8018f8 (patch)
treeaa1a1ecd332a4e3fceffbeeb60b9425123644434 /rust
parent334238e68398bd4e1e84a0b2931a71129100ef6a (diff)
parent2ea0119f72dba597aa8a98cbdb72c564bfc5cb38 (diff)
Merge tag 'rust-timekeeping-for-v7.4-rc1' of https://github.com/Rust-for-Linux/linux into rust-next
Pull timekeeping updates from Andreas Hindborg: - Warn and assert when passing out-of-range inputs to 'fsleep' and 'udelay'. - Rename 'ClockSource' to 'ClockId' to better align with naming conventions in C kernel. - Make 'CONFIG_HZ' value available as 'bindings::HZ'. - Add a conversion method to convert 'Delta' to 'jiffies' for use in timeout arguments. - Add implementation detail documentation for 'HrTimer'. * tag 'rust-timekeeping-for-v7.4-rc1' of https://github.com/Rust-for-Linux/linux: rust: hrtimer: document handle based design rationale rust: time: add Delta::to_jiffies_timeout() for timeout conversion rust: bindings: set HZ to CONFIG_HZ rust: time: rename ClockSource trait to ClockId rust: time: warn and assert out-of-range input in fsleep() and udelay()
Diffstat (limited to 'rust')
-rw-r--r--rust/bindings/lib.rs5
-rw-r--r--rust/helpers/helpers.c1
-rw-r--r--rust/helpers/math.c8
-rw-r--r--rust/kernel/Kconfig.test10
-rw-r--r--rust/kernel/time.rs139
-rw-r--r--rust/kernel/time/delay.rs17
-rw-r--r--rust/kernel/time/hrtimer.rs95
7 files changed, 211 insertions, 64 deletions
diff --git a/rust/bindings/lib.rs b/rust/bindings/lib.rs
index 439ab88a5da1..98313fc31024 100644
--- a/rust/bindings/lib.rs
+++ b/rust/bindings/lib.rs
@@ -83,3 +83,8 @@ pub const compat_ptr_ioctl: Option<
None
}
};
+
+// `bindgen` keeps the first definition of a macro and ignores a later `#undef`.
+// The generated `HZ` is therefore `__USER_HZ` from
+// `include/uapi/asm-generic/param.h`, not `CONFIG_HZ`.
+pub const HZ: u32 = CONFIG_HZ;
diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
index 440fb7638e3c..08374b163774 100644
--- a/rust/helpers/helpers.c
+++ b/rust/helpers/helpers.c
@@ -73,6 +73,7 @@
#include "kunit.c"
#include "list.c"
#include "maple_tree.c"
+#include "math.c"
#include "mm.c"
#include "mutex.c"
#include "net/genetlink.c"
diff --git a/rust/helpers/math.c b/rust/helpers/math.c
new file mode 100644
index 000000000000..e2ee29bcce0f
--- /dev/null
+++ b/rust/helpers/math.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/math64.h>
+
+__rust_helper u64 rust_helper_mul_u64_add_u64_div_u64(u64 a, u64 b, u64 c, u64 d)
+{
+ return mul_u64_add_u64_div_u64(a, b, c, d);
+}
diff --git a/rust/kernel/Kconfig.test b/rust/kernel/Kconfig.test
index 966b07872ba1..3bf4194f28c7 100644
--- a/rust/kernel/Kconfig.test
+++ b/rust/kernel/Kconfig.test
@@ -94,4 +94,14 @@ config RUST_BUG_KUNIT_TEST
If unsure, say N.
+config RUST_TIME_KUNIT_TEST
+ bool "KUnit tests for the Rust time API" if !KUNIT_ALL_TESTS
+ default KUNIT_ALL_TESTS
+ help
+ This option enables KUnit tests for the Rust time API.
+ These are only for development and testing, not for regular
+ kernel use cases.
+
+ If unsure, say N.
+
endif
diff --git a/rust/kernel/time.rs b/rust/kernel/time.rs
index 6c0a5e8090d0..5ae377e70dd8 100644
--- a/rust/kernel/time.rs
+++ b/rust/kernel/time.rs
@@ -39,6 +39,10 @@ pub const NSEC_PER_MSEC: i64 = bindings::NSEC_PER_MSEC as i64;
/// The number of nanoseconds per second.
pub const NSEC_PER_SEC: i64 = bindings::NSEC_PER_SEC as i64;
+/// The C side `MAX_JIFFY_OFFSET`, i.e. `((LONG_MAX >> 1) - 1)`. It is the upper
+/// bound the kernel uses for a jiffies span, not a wait-forever value.
+const MAX_JIFFY_OFFSET: isize = (isize::MAX >> 1) - 1;
+
/// The time unit of Linux kernel. One jiffy equals (1/HZ) second.
pub type Jiffies = crate::ffi::c_ulong;
@@ -53,9 +57,9 @@ pub fn msecs_to_jiffies(msecs: Msecs) -> Jiffies {
unsafe { bindings::__msecs_to_jiffies(msecs) }
}
-/// Trait for clock sources.
+/// Trait for kernel clock identifiers.
///
-/// Selection of the clock source depends on the use case. In some cases the usage of a
+/// Selection of the clock depends on the use case. In some cases the usage of a
/// particular clock is mandatory, e.g. in network protocols, filesystems. In other
/// cases the user of the clock has to decide which clock is best suited for the
/// purpose. In most scenarios clock [`Monotonic`] is the best choice as it
@@ -66,13 +70,13 @@ pub fn msecs_to_jiffies(msecs: Msecs) -> Jiffies {
/// Implementers must ensure that `ktime_get()` returns a value in the inclusive range
/// `0..=KTIME_MAX` (i.e., greater than or equal to 0 and less than or equal to
/// `KTIME_MAX`, where `KTIME_MAX` equals `i64::MAX`).
-pub unsafe trait ClockSource {
- /// The kernel clock ID associated with this clock source.
+pub unsafe trait ClockId {
+ /// The kernel clock ID associated with this clock.
///
/// This constant corresponds to the C side `clockid_t` value.
const ID: bindings::clockid_t;
- /// Get the current time from the clock source.
+ /// Get the current time from the clock.
///
/// The function must return a value in the range `0..=KTIME_MAX`.
fn ktime_get() -> bindings::ktime_t;
@@ -93,7 +97,7 @@ pub struct Monotonic;
// SAFETY: The kernel's `ktime_get()` is guaranteed to return a value
// in `0..=KTIME_MAX`.
-unsafe impl ClockSource for Monotonic {
+unsafe impl ClockId for Monotonic {
const ID: bindings::clockid_t = bindings::CLOCK_MONOTONIC as bindings::clockid_t;
fn ktime_get() -> bindings::ktime_t {
@@ -120,7 +124,7 @@ pub struct RealTime;
// SAFETY: The kernel's `ktime_get_real()` is guaranteed to return a value
// in `0..=KTIME_MAX`.
-unsafe impl ClockSource for RealTime {
+unsafe impl ClockId for RealTime {
const ID: bindings::clockid_t = bindings::CLOCK_REALTIME as bindings::clockid_t;
fn ktime_get() -> bindings::ktime_t {
@@ -140,7 +144,7 @@ pub struct BootTime;
// SAFETY: The kernel's `ktime_get_boottime()` is guaranteed to return a value
// in `0..=KTIME_MAX`.
-unsafe impl ClockSource for BootTime {
+unsafe impl ClockId for BootTime {
const ID: bindings::clockid_t = bindings::CLOCK_BOOTTIME as bindings::clockid_t;
fn ktime_get() -> bindings::ktime_t {
@@ -164,7 +168,7 @@ pub struct Tai;
// SAFETY: The kernel's `ktime_get_clocktai()` is guaranteed to return a value
// in `0..=KTIME_MAX`.
-unsafe impl ClockSource for Tai {
+unsafe impl ClockId for Tai {
const ID: bindings::clockid_t = bindings::CLOCK_TAI as bindings::clockid_t;
fn ktime_get() -> bindings::ktime_t {
@@ -180,24 +184,24 @@ unsafe impl ClockSource for Tai {
/// The `inner` value is in the range from 0 to `KTIME_MAX`.
#[repr(transparent)]
#[derive(PartialEq, PartialOrd, Eq, Ord)]
-pub struct Instant<C: ClockSource> {
+pub struct Instant<C: ClockId> {
inner: bindings::ktime_t,
_c: PhantomData<C>,
}
-impl<C: ClockSource> Clone for Instant<C> {
+impl<C: ClockId> Clone for Instant<C> {
fn clone(&self) -> Self {
*self
}
}
-impl<C: ClockSource> Copy for Instant<C> {}
+impl<C: ClockId> Copy for Instant<C> {}
-impl<C: ClockSource> Instant<C> {
+impl<C: ClockId> Instant<C> {
/// Get the current time from the clock source.
#[inline]
pub fn now() -> Self {
- // INVARIANT: The `ClockSource::ktime_get()` function returns a value in the range
+ // INVARIANT: The `ClockId::ktime_get()` function returns a value in the range
// from 0 to `KTIME_MAX`.
Self {
inner: C::ktime_get(),
@@ -239,7 +243,7 @@ impl<C: ClockSource> Instant<C> {
}
}
-impl<C: ClockSource> ops::Sub for Instant<C> {
+impl<C: ClockId> ops::Sub for Instant<C> {
type Output = Delta;
// By the type invariant, it never overflows.
@@ -251,7 +255,7 @@ impl<C: ClockSource> ops::Sub for Instant<C> {
}
}
-impl<T: ClockSource> ops::Add<Delta> for Instant<T> {
+impl<T: ClockId> ops::Add<Delta> for Instant<T> {
type Output = Self;
#[inline]
@@ -271,7 +275,7 @@ impl<T: ClockSource> ops::Add<Delta> for Instant<T> {
}
}
-impl<T: ClockSource> ops::Sub<Delta> for Instant<T> {
+impl<T: ClockId> ops::Sub<Delta> for Instant<T> {
type Output = Self;
#[inline]
@@ -554,6 +558,62 @@ impl Delta {
}
}
+ /// Convert this span to a [`Delta<Jiffy>`] suitable for use as a timeout.
+ ///
+ /// Unless the result saturates, the value is rounded up to the next whole
+ /// jiffy, so the resulting timeout is never shorter than `self`.
+ ///
+ /// A negative span saturates at zero jiffies, i.e. an immediate timeout.
+ ///
+ /// A span that does not fit saturates at the kernel's [`MAX_JIFFY_OFFSET`],
+ /// the upper bound for a jiffies span. That is a finite timeout, so a
+ /// saturated result can be shorter than the requested span. It is derived
+ /// from `long`, so only 32 bit can reach it, at about 12 days with `HZ=1000`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use kernel::time::Delta;
+ ///
+ /// // A negative span is an immediate timeout.
+ /// assert_eq!(Delta::from_millis(-1).to_jiffies_timeout().as_jiffies(), 0);
+ ///
+ /// // A span shorter than a jiffy still waits, i.e. the timeout is never
+ /// // shorter than the span.
+ /// assert!(Delta::from_nanos(1).to_jiffies_timeout().as_jiffies() >= 1);
+ /// ```
+ ///
+ /// [`MAX_JIFFY_OFFSET`]: srctree/include/linux/jiffies.h
+ #[inline]
+ pub fn to_jiffies_timeout(self) -> Delta<Jiffy> {
+ const HZ: u64 = bindings::HZ as u64;
+
+ // The quotient `(nsecs * HZ + NSEC_PER_SEC - 1) / NSEC_PER_SEC` has to fit in
+ // `u64`; `nsecs * HZ` does not. With `HZ <= NSEC_PER_SEC` the numerator is at
+ // most `(nsecs + 1) * NSEC_PER_SEC - 1`, so the quotient is at most `nsecs`.
+ crate::static_assert!(HZ <= NSEC_PER_SEC as u64);
+
+ // CAST: `i64::max()` makes the value non-negative, so the cast keeps it.
+ let nsecs = i64::max(self.as_nanos(), 0) as u64;
+
+ // SAFETY: `mul_u64_add_u64_div_u64()` must not be called with a zero divisor,
+ // and its result must fit in `u64`. `NSEC_PER_SEC` is a non-zero constant, and
+ // the assertion above bounds the quotient by `nsecs`.
+ let jiffies = unsafe {
+ bindings::mul_u64_add_u64_div_u64(
+ nsecs,
+ HZ,
+ (NSEC_PER_SEC - 1) as u64,
+ NSEC_PER_SEC as u64,
+ )
+ };
+
+ // CAST: `jiffies` is clamped to `MAX_JIFFY_OFFSET`, which is `<= isize::MAX`.
+ let jiffies = u64::min(jiffies, MAX_JIFFY_OFFSET as u64) as isize;
+
+ Delta::<Jiffy>::from_jiffies(jiffies)
+ }
+
/// 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
@@ -580,3 +640,48 @@ impl Delta {
}
}
}
+
+#[cfg(CONFIG_RUST_TIME_KUNIT_TEST)]
+#[macros::kunit_tests(rust_kernel_time)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn to_jiffies_timeout_converts() {
+ const HZ: isize = bindings::HZ as isize;
+
+ // One second is exactly `HZ` jiffies, and the round-up must not add one.
+ assert_eq!(Delta::from_secs(1).to_jiffies_timeout().as_jiffies(), HZ);
+
+ // One nanosecond more has to round up to the next whole jiffy.
+ assert_eq!(
+ Delta::from_nanos(NSEC_PER_SEC + 1)
+ .to_jiffies_timeout()
+ .as_jiffies(),
+ HZ + 1
+ );
+ }
+
+ #[test]
+ fn to_jiffies_timeout_saturates() {
+ // The result never exceeds `MAX_JIFFY_OFFSET`. On 32 bit with `HZ=1000` this
+ // span is 2147483647 jiffies, so the clamp is what keeps it in range; on 64
+ // bit it fits and the check holds for every possible return value.
+ let clamped = Delta::from_millis(i64::from(i32::MAX)).to_jiffies_timeout();
+ assert!(clamped.as_jiffies() <= MAX_JIFFY_OFFSET);
+
+ // `MAX_JIFFY_OFFSET` is derived from `long`, so only 32 bit can reach it. On
+ // 64 bit `i64::MAX` nanoseconds is about 292 years, which is 9223372036855
+ // jiffies with `HZ=1000`, far below the limit.
+ #[cfg(not(CONFIG_64BIT))]
+ {
+ // An overlong span is clamped to `MAX_JIFFY_OFFSET`.
+ let overlong = Delta::from_nanos(i64::MAX).to_jiffies_timeout();
+ assert_eq!(overlong.as_jiffies(), MAX_JIFFY_OFFSET);
+ }
+
+ // A negative span is an immediate timeout, however long it is.
+ let negative = Delta::from_nanos(i64::MIN).to_jiffies_timeout();
+ assert_eq!(negative.as_jiffies(), 0);
+ }
+}
diff --git a/rust/kernel/time/delay.rs b/rust/kernel/time/delay.rs
index b5b1b42797a0..4debe23731bf 100644
--- a/rust/kernel/time/delay.rs
+++ b/rust/kernel/time/delay.rs
@@ -8,7 +8,10 @@
//! C header: [`include/linux/delay.h`](srctree/include/linux/delay.h).
use super::Delta;
-use crate::prelude::*;
+use crate::{
+ pr_warn_once,
+ prelude::*, //
+};
/// Sleeps for a given duration at least.
///
@@ -18,8 +21,7 @@ use crate::prelude::*;
/// `delta` must be within `[0, i32::MAX]` microseconds;
/// otherwise, it is erroneous behavior. That is, it is considered a bug
/// to call this function with an out-of-range value, in which case the function
-/// will sleep for at least the maximum value in the range and may warn
-/// in the future.
+/// will sleep for at least the maximum value in the range and warns once.
///
/// The behavior above differs from the C side [`fsleep()`] for which out-of-range
/// values mean "infinite timeout" instead.
@@ -32,10 +34,13 @@ pub fn fsleep(delta: Delta) {
// overflow inside fsleep, which could lead to unintentional infinite sleep.
const MAX_DELTA: Delta = Delta::from_micros(i32::MAX as i64);
+ debug_assert!(delta.as_nanos() >= 0);
+ debug_assert!(delta <= MAX_DELTA);
+
let delta = if (Delta::ZERO..=MAX_DELTA).contains(&delta) {
delta
} else {
- // TODO: Add WARN_ONCE() when it's supported.
+ pr_warn_once!("attempted to fsleep() with out of range delta\n");
MAX_DELTA
};
@@ -54,7 +59,8 @@ pub fn fsleep(delta: Delta) {
///
/// `delta` must be within `[0, MAX_UDELAY_MS]` in milliseconds;
/// otherwise, it is erroneous behavior. That is, it is considered a bug to
-/// call this function with an out-of-range value.
+/// call this function with an out-of-range value, in which case the function
+/// will delay for at least the maximum value in the range and warns once.
///
/// The behavior above differs from the C side [`udelay()`] for which out-of-range
/// values could lead to an overflow and unexpected behavior.
@@ -69,6 +75,7 @@ pub fn udelay(delta: Delta) {
let delta = if (Delta::ZERO..=MAX_UDELAY_DELTA).contains(&delta) {
delta
} else {
+ pr_warn_once!("attempted to udelay() with out of range delta\n");
MAX_UDELAY_DELTA
};
diff --git a/rust/kernel/time/hrtimer.rs b/rust/kernel/time/hrtimer.rs
index 2d7f1131a813..c0180b8ca5d3 100644
--- a/rust/kernel/time/hrtimer.rs
+++ b/rust/kernel/time/hrtimer.rs
@@ -402,15 +402,26 @@
//! ```
//!
//! [`Arc`]: kernel::sync::Arc
-
-use super::{ClockSource, Delta, Instant};
+// Implementation details
+//
+// The reasoning for adopting a handle based approach:
+// - If we explicitly drop the target of a timer callback in the timer callback, we
+// may get a dangling reference.
+// - If the callback owns the last reference to the target, target may be dropped
+// in non-sleepable context when the callback is finished.
+// - When dropping an object that is the target of an armed timer, we may drop
+// fields accessed by the timer callback before we cancel the timer (drop order).
+//
+// By using a handle, we can make the handle own the callback target and avoid these problems.
+
+use super::{ClockId, Delta, Instant};
use crate::{prelude::*, types::Opaque};
use core::{marker::PhantomData, ptr::NonNull};
use pin_init::PinInit;
/// A type-alias to refer to the [`Instant<C>`] for a given `T` from [`HrTimer<T>`].
///
-/// Where `C` is the [`ClockSource`] of the [`HrTimer`].
+/// Where `C` is the [`ClockId`] of the [`HrTimer`].
pub type HrTimerInstant<T> = Instant<<<T as HasHrTimer<T>>::TimerMode as HrTimerMode>::Clock>;
/// A timer backed by a C `struct hrtimer`.
@@ -855,7 +866,7 @@ pub trait HrTimerExpires {
fn as_nanos(&self) -> i64;
}
-impl<C: ClockSource> HrTimerExpires for Instant<C> {
+impl<C: ClockId> HrTimerExpires for Instant<C> {
#[inline]
fn as_nanos(&self) -> i64 {
Instant::<C>::as_nanos(self)
@@ -870,22 +881,22 @@ impl HrTimerExpires for Delta {
}
mod private {
- use crate::time::ClockSource;
+ use crate::time::ClockId;
pub trait Sealed {}
- impl<C: ClockSource> Sealed for super::AbsoluteMode<C> {}
- impl<C: ClockSource> Sealed for super::RelativeMode<C> {}
- impl<C: ClockSource> Sealed for super::AbsolutePinnedMode<C> {}
- impl<C: ClockSource> Sealed for super::RelativePinnedMode<C> {}
- impl<C: ClockSource> Sealed for super::AbsoluteSoftMode<C> {}
- impl<C: ClockSource> Sealed for super::RelativeSoftMode<C> {}
- impl<C: ClockSource> Sealed for super::AbsolutePinnedSoftMode<C> {}
- impl<C: ClockSource> Sealed for super::RelativePinnedSoftMode<C> {}
- impl<C: ClockSource> Sealed for super::AbsoluteHardMode<C> {}
- impl<C: ClockSource> Sealed for super::RelativeHardMode<C> {}
- impl<C: ClockSource> Sealed for super::AbsolutePinnedHardMode<C> {}
- impl<C: ClockSource> Sealed for super::RelativePinnedHardMode<C> {}
+ impl<C: ClockId> Sealed for super::AbsoluteMode<C> {}
+ impl<C: ClockId> Sealed for super::RelativeMode<C> {}
+ impl<C: ClockId> Sealed for super::AbsolutePinnedMode<C> {}
+ impl<C: ClockId> Sealed for super::RelativePinnedMode<C> {}
+ impl<C: ClockId> Sealed for super::AbsoluteSoftMode<C> {}
+ impl<C: ClockId> Sealed for super::RelativeSoftMode<C> {}
+ impl<C: ClockId> Sealed for super::AbsolutePinnedSoftMode<C> {}
+ impl<C: ClockId> Sealed for super::RelativePinnedSoftMode<C> {}
+ impl<C: ClockId> Sealed for super::AbsoluteHardMode<C> {}
+ impl<C: ClockId> Sealed for super::RelativeHardMode<C> {}
+ impl<C: ClockId> Sealed for super::AbsolutePinnedHardMode<C> {}
+ impl<C: ClockId> Sealed for super::RelativePinnedHardMode<C> {}
}
/// Operational mode of [`HrTimer`].
@@ -894,16 +905,16 @@ pub trait HrTimerMode: private::Sealed {
const C_MODE: bindings::hrtimer_mode;
/// Type representing the clock source.
- type Clock: ClockSource;
+ type Clock: ClockId;
/// Type representing the expiration specification (absolute or relative time).
type Expires: HrTimerExpires;
}
/// Timer that expires at a fixed point in time.
-pub struct AbsoluteMode<C: ClockSource>(PhantomData<C>);
+pub struct AbsoluteMode<C: ClockId>(PhantomData<C>);
-impl<C: ClockSource> HrTimerMode for AbsoluteMode<C> {
+impl<C: ClockId> HrTimerMode for AbsoluteMode<C> {
const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_ABS;
type Clock = C;
@@ -911,9 +922,9 @@ impl<C: ClockSource> HrTimerMode for AbsoluteMode<C> {
}
/// Timer that expires after a delay from now.
-pub struct RelativeMode<C: ClockSource>(PhantomData<C>);
+pub struct RelativeMode<C: ClockId>(PhantomData<C>);
-impl<C: ClockSource> HrTimerMode for RelativeMode<C> {
+impl<C: ClockId> HrTimerMode for RelativeMode<C> {
const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_REL;
type Clock = C;
@@ -921,8 +932,8 @@ impl<C: ClockSource> HrTimerMode for RelativeMode<C> {
}
/// Timer with absolute expiration time, pinned to its current CPU.
-pub struct AbsolutePinnedMode<C: ClockSource>(PhantomData<C>);
-impl<C: ClockSource> HrTimerMode for AbsolutePinnedMode<C> {
+pub struct AbsolutePinnedMode<C: ClockId>(PhantomData<C>);
+impl<C: ClockId> HrTimerMode for AbsolutePinnedMode<C> {
const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_ABS_PINNED;
type Clock = C;
@@ -930,8 +941,8 @@ impl<C: ClockSource> HrTimerMode for AbsolutePinnedMode<C> {
}
/// Timer with relative expiration time, pinned to its current CPU.
-pub struct RelativePinnedMode<C: ClockSource>(PhantomData<C>);
-impl<C: ClockSource> HrTimerMode for RelativePinnedMode<C> {
+pub struct RelativePinnedMode<C: ClockId>(PhantomData<C>);
+impl<C: ClockId> HrTimerMode for RelativePinnedMode<C> {
const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_REL_PINNED;
type Clock = C;
@@ -939,8 +950,8 @@ impl<C: ClockSource> HrTimerMode for RelativePinnedMode<C> {
}
/// Timer with absolute expiration, handled in soft irq context.
-pub struct AbsoluteSoftMode<C: ClockSource>(PhantomData<C>);
-impl<C: ClockSource> HrTimerMode for AbsoluteSoftMode<C> {
+pub struct AbsoluteSoftMode<C: ClockId>(PhantomData<C>);
+impl<C: ClockId> HrTimerMode for AbsoluteSoftMode<C> {
const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_ABS_SOFT;
type Clock = C;
@@ -948,8 +959,8 @@ impl<C: ClockSource> HrTimerMode for AbsoluteSoftMode<C> {
}
/// Timer with relative expiration, handled in soft irq context.
-pub struct RelativeSoftMode<C: ClockSource>(PhantomData<C>);
-impl<C: ClockSource> HrTimerMode for RelativeSoftMode<C> {
+pub struct RelativeSoftMode<C: ClockId>(PhantomData<C>);
+impl<C: ClockId> HrTimerMode for RelativeSoftMode<C> {
const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_REL_SOFT;
type Clock = C;
@@ -957,8 +968,8 @@ impl<C: ClockSource> HrTimerMode for RelativeSoftMode<C> {
}
/// Timer with absolute expiration, pinned to CPU and handled in soft irq context.
-pub struct AbsolutePinnedSoftMode<C: ClockSource>(PhantomData<C>);
-impl<C: ClockSource> HrTimerMode for AbsolutePinnedSoftMode<C> {
+pub struct AbsolutePinnedSoftMode<C: ClockId>(PhantomData<C>);
+impl<C: ClockId> HrTimerMode for AbsolutePinnedSoftMode<C> {
const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_ABS_PINNED_SOFT;
type Clock = C;
@@ -966,8 +977,8 @@ impl<C: ClockSource> HrTimerMode for AbsolutePinnedSoftMode<C> {
}
/// Timer with absolute expiration, pinned to CPU and handled in soft irq context.
-pub struct RelativePinnedSoftMode<C: ClockSource>(PhantomData<C>);
-impl<C: ClockSource> HrTimerMode for RelativePinnedSoftMode<C> {
+pub struct RelativePinnedSoftMode<C: ClockId>(PhantomData<C>);
+impl<C: ClockId> HrTimerMode for RelativePinnedSoftMode<C> {
const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_REL_PINNED_SOFT;
type Clock = C;
@@ -975,8 +986,8 @@ impl<C: ClockSource> HrTimerMode for RelativePinnedSoftMode<C> {
}
/// Timer with absolute expiration, handled in hard irq context.
-pub struct AbsoluteHardMode<C: ClockSource>(PhantomData<C>);
-impl<C: ClockSource> HrTimerMode for AbsoluteHardMode<C> {
+pub struct AbsoluteHardMode<C: ClockId>(PhantomData<C>);
+impl<C: ClockId> HrTimerMode for AbsoluteHardMode<C> {
const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_ABS_HARD;
type Clock = C;
@@ -984,8 +995,8 @@ impl<C: ClockSource> HrTimerMode for AbsoluteHardMode<C> {
}
/// Timer with relative expiration, handled in hard irq context.
-pub struct RelativeHardMode<C: ClockSource>(PhantomData<C>);
-impl<C: ClockSource> HrTimerMode for RelativeHardMode<C> {
+pub struct RelativeHardMode<C: ClockId>(PhantomData<C>);
+impl<C: ClockId> HrTimerMode for RelativeHardMode<C> {
const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_REL_HARD;
type Clock = C;
@@ -993,8 +1004,8 @@ impl<C: ClockSource> HrTimerMode for RelativeHardMode<C> {
}
/// Timer with absolute expiration, pinned to CPU and handled in hard irq context.
-pub struct AbsolutePinnedHardMode<C: ClockSource>(PhantomData<C>);
-impl<C: ClockSource> HrTimerMode for AbsolutePinnedHardMode<C> {
+pub struct AbsolutePinnedHardMode<C: ClockId>(PhantomData<C>);
+impl<C: ClockId> HrTimerMode for AbsolutePinnedHardMode<C> {
const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_ABS_PINNED_HARD;
type Clock = C;
@@ -1002,8 +1013,8 @@ impl<C: ClockSource> HrTimerMode for AbsolutePinnedHardMode<C> {
}
/// Timer with relative expiration, pinned to CPU and handled in hard irq context.
-pub struct RelativePinnedHardMode<C: ClockSource>(PhantomData<C>);
-impl<C: ClockSource> HrTimerMode for RelativePinnedHardMode<C> {
+pub struct RelativePinnedHardMode<C: ClockId>(PhantomData<C>);
+impl<C: ClockId> HrTimerMode for RelativePinnedHardMode<C> {
const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_REL_PINNED_HARD;
type Clock = C;