From ced9ccd21fbc8ca941e6a0c2820c2df89239ccb9 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 10 Jun 2025 22:28:20 +0900 Subject: [PATCH] rust: time: Replace HrTimerMode enum with trait-based mode types Replace the `HrTimerMode` enum with a trait-based approach that uses zero-sized types to represent each mode of operation. Each mode now implements the `HrTimerMode` trait. This refactoring is a preparation for replacing raw `Ktime` in HrTimer with the `Instant` and `Delta` types, and for making `HrTimer` generic over a `ClockSource`. Reviewed-by: Andreas Hindborg Signed-off-by: FUJITA Tomonori Link: https://lore.kernel.org/r/20250610132823.3457263-3-fujita.tomonori@gmail.com Signed-off-by: Andreas Hindborg --- rust/kernel/time/hrtimer.rs | 164 ++++++++++++++++++++---------------- 1 file changed, 90 insertions(+), 74 deletions(-) diff --git a/rust/kernel/time/hrtimer.rs b/rust/kernel/time/hrtimer.rs index 20b87a4d65aec..b6322f4b860f4 100644 --- a/rust/kernel/time/hrtimer.rs +++ b/rust/kernel/time/hrtimer.rs @@ -98,7 +98,7 @@ impl Ktime { pub struct HrTimer { #[pin] timer: Opaque, - mode: HrTimerMode, + mode: bindings::hrtimer_mode, _t: PhantomData, } @@ -112,7 +112,7 @@ unsafe impl Sync for HrTimer {} impl HrTimer { /// Return an initializer for a new timer instance. - pub fn new(mode: HrTimerMode) -> impl PinInit + pub fn new() -> impl PinInit where T: HrTimerCallback, { @@ -127,11 +127,11 @@ impl HrTimer { place, Some(T::Pointer::run), U::ID, - mode.into_c(), + M::C_MODE, ); } }), - mode: mode, + mode: M::C_MODE, _t: PhantomData, }) } @@ -389,7 +389,7 @@ pub unsafe trait HasHrTimer { Self::c_timer_ptr(this).cast_mut(), expires.to_ns(), 0, - (*Self::raw_get_timer(this)).mode.into_c(), + (*Self::raw_get_timer(this)).mode, ); } } @@ -412,77 +412,93 @@ impl HrTimerRestart { } /// Operational mode of [`HrTimer`]. -// NOTE: Some of these have the same encoding on the C side, so we keep -// `repr(Rust)` and convert elsewhere. -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub enum HrTimerMode { - /// Timer expires at the given expiration time. - Absolute, - /// Timer expires after the given expiration time interpreted as a duration from now. - Relative, - /// Timer does not move between CPU cores. - Pinned, - /// Timer handler is executed in soft irq context. - Soft, - /// Timer handler is executed in hard irq context. - Hard, - /// Timer expires at the given expiration time. - /// Timer does not move between CPU cores. - AbsolutePinned, - /// Timer expires after the given expiration time interpreted as a duration from now. - /// Timer does not move between CPU cores. - RelativePinned, - /// Timer expires at the given expiration time. - /// Timer handler is executed in soft irq context. - AbsoluteSoft, - /// Timer expires after the given expiration time interpreted as a duration from now. - /// Timer handler is executed in soft irq context. - RelativeSoft, - /// Timer expires at the given expiration time. - /// Timer does not move between CPU cores. - /// Timer handler is executed in soft irq context. - AbsolutePinnedSoft, - /// Timer expires after the given expiration time interpreted as a duration from now. - /// Timer does not move between CPU cores. - /// Timer handler is executed in soft irq context. - RelativePinnedSoft, - /// Timer expires at the given expiration time. - /// Timer handler is executed in hard irq context. - AbsoluteHard, - /// Timer expires after the given expiration time interpreted as a duration from now. - /// Timer handler is executed in hard irq context. - RelativeHard, - /// Timer expires at the given expiration time. - /// Timer does not move between CPU cores. - /// Timer handler is executed in hard irq context. - AbsolutePinnedHard, - /// Timer expires after the given expiration time interpreted as a duration from now. - /// Timer does not move between CPU cores. - /// Timer handler is executed in hard irq context. - RelativePinnedHard, +pub trait HrTimerMode { + /// The C representation of hrtimer mode. + const C_MODE: bindings::hrtimer_mode; } -impl HrTimerMode { - fn into_c(self) -> bindings::hrtimer_mode { - use bindings::*; - match self { - HrTimerMode::Absolute => hrtimer_mode_HRTIMER_MODE_ABS, - HrTimerMode::Relative => hrtimer_mode_HRTIMER_MODE_REL, - HrTimerMode::Pinned => hrtimer_mode_HRTIMER_MODE_PINNED, - HrTimerMode::Soft => hrtimer_mode_HRTIMER_MODE_SOFT, - HrTimerMode::Hard => hrtimer_mode_HRTIMER_MODE_HARD, - HrTimerMode::AbsolutePinned => hrtimer_mode_HRTIMER_MODE_ABS_PINNED, - HrTimerMode::RelativePinned => hrtimer_mode_HRTIMER_MODE_REL_PINNED, - HrTimerMode::AbsoluteSoft => hrtimer_mode_HRTIMER_MODE_ABS_SOFT, - HrTimerMode::RelativeSoft => hrtimer_mode_HRTIMER_MODE_REL_SOFT, - HrTimerMode::AbsolutePinnedSoft => hrtimer_mode_HRTIMER_MODE_ABS_PINNED_SOFT, - HrTimerMode::RelativePinnedSoft => hrtimer_mode_HRTIMER_MODE_REL_PINNED_SOFT, - HrTimerMode::AbsoluteHard => hrtimer_mode_HRTIMER_MODE_ABS_HARD, - HrTimerMode::RelativeHard => hrtimer_mode_HRTIMER_MODE_REL_HARD, - HrTimerMode::AbsolutePinnedHard => hrtimer_mode_HRTIMER_MODE_ABS_PINNED_HARD, - HrTimerMode::RelativePinnedHard => hrtimer_mode_HRTIMER_MODE_REL_PINNED_HARD, - } - } +/// Timer that expires at a fixed point in time. +pub struct AbsoluteMode; + +impl HrTimerMode for AbsoluteMode { + const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_ABS; +} + +/// Timer that expires after a delay from now. +pub struct RelativeMode; + +impl HrTimerMode for RelativeMode { + const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_REL; +} + +/// Timer with absolute expiration time, pinned to its current CPU. +pub struct AbsolutePinnedMode; + +impl HrTimerMode for AbsolutePinnedMode { + const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_ABS_PINNED; +} + +/// Timer with relative expiration time, pinned to its current CPU. +pub struct RelativePinnedMode; + +impl HrTimerMode for RelativePinnedMode { + const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_REL_PINNED; +} + +/// Timer with absolute expiration, handled in soft irq context. +pub struct AbsoluteSoftMode; + +impl HrTimerMode for AbsoluteSoftMode { + const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_ABS_SOFT; +} + +/// Timer with relative expiration, handled in soft irq context. +pub struct RelativeSoftMode; + +impl HrTimerMode for RelativeSoftMode { + const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_REL_SOFT; +} + +/// Timer with absolute expiration, pinned to CPU and handled in soft irq context. +pub struct AbsolutePinnedSoftMode; + +impl HrTimerMode for AbsolutePinnedSoftMode { + const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_ABS_PINNED_SOFT; +} + +/// Timer with relative expiration, pinned to CPU and handled in soft irq context. +pub struct RelativePinnedSoftMode; + +impl HrTimerMode for RelativePinnedSoftMode { + const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_REL_PINNED_SOFT; +} + +/// Timer with absolute expiration, handled in hard irq context. +pub struct AbsoluteHardMode; + +impl HrTimerMode for AbsoluteHardMode { + const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_ABS_HARD; +} + +/// Timer with relative expiration, handled in hard irq context. +pub struct RelativeHardMode; + +impl HrTimerMode for RelativeHardMode { + const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_REL_HARD; +} + +/// Timer with absolute expiration, pinned to CPU and handled in hard irq context. +pub struct AbsolutePinnedHardMode; + +impl HrTimerMode for AbsolutePinnedHardMode { + const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_ABS_PINNED_HARD; +} + +/// Timer with relative expiration, pinned to CPU and handled in hard irq context. +pub struct RelativePinnedHardMode; + +impl HrTimerMode for RelativePinnedHardMode { + const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_REL_PINNED_HARD; } /// Use to implement the [`HasHrTimer`] trait. -- 2.47.2