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 <a.hindborg@kernel.org>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
Link: https://lore.kernel.org/r/20250610132823.3457263-3-fujita.tomonori@gmail.com
Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
This commit is contained in:
FUJITA Tomonori 2025-06-10 22:28:20 +09:00 committed by Andreas Hindborg
parent cc6d1098b4
commit ced9ccd21f

View File

@ -98,7 +98,7 @@ impl Ktime {
pub struct HrTimer<T> {
#[pin]
timer: Opaque<bindings::hrtimer>,
mode: HrTimerMode,
mode: bindings::hrtimer_mode,
_t: PhantomData<T>,
}
@ -112,7 +112,7 @@ unsafe impl<T> Sync for HrTimer<T> {}
impl<T> HrTimer<T> {
/// Return an initializer for a new timer instance.
pub fn new<U: ClockSource>(mode: HrTimerMode) -> impl PinInit<Self>
pub fn new<U: ClockSource, M: HrTimerMode>() -> impl PinInit<Self>
where
T: HrTimerCallback,
{
@ -127,11 +127,11 @@ impl<T> HrTimer<T> {
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<T> {
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<T>`] trait.