rust: hrtimer: add clocksource selection through `ClockId`

Allow selecting a clock source for timers by passing a `ClockId`
variant to `HrTimer::new`.

Acked-by: Frederic Weisbecker <frederic@kernel.org>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/20250309-hrtimer-v3-v6-12-rc2-v12-12-73586e2bd5f1@kernel.org
Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>

+69 -2
+66
rust/kernel/time.rs
··· 83 83 } 84 84 } 85 85 } 86 + 87 + /// An identifier for a clock. Used when specifying clock sources. 88 + /// 89 + /// 90 + /// Selection of the clock depends on the use case. In some cases the usage of a 91 + /// particular clock is mandatory, e.g. in network protocols, filesystems.In other 92 + /// cases the user of the clock has to decide which clock is best suited for the 93 + /// purpose. In most scenarios clock [`ClockId::Monotonic`] is the best choice as it 94 + /// provides a accurate monotonic notion of time (leap second smearing ignored). 95 + #[derive(Clone, Copy, PartialEq, Eq, Debug)] 96 + #[repr(u32)] 97 + pub enum ClockId { 98 + /// A settable system-wide clock that measures real (i.e., wall-clock) time. 99 + /// 100 + /// Setting this clock requires appropriate privileges. This clock is 101 + /// affected by discontinuous jumps in the system time (e.g., if the system 102 + /// administrator manually changes the clock), and by frequency adjustments 103 + /// performed by NTP and similar applications via adjtime(3), adjtimex(2), 104 + /// clock_adjtime(2), and ntp_adjtime(3). This clock normally counts the 105 + /// number of seconds since 1970-01-01 00:00:00 Coordinated Universal Time 106 + /// (UTC) except that it ignores leap seconds; near a leap second it may be 107 + /// adjusted by leap second smearing to stay roughly in sync with UTC. Leap 108 + /// second smearing applies frequency adjustments to the clock to speed up 109 + /// or slow down the clock to account for the leap second without 110 + /// discontinuities in the clock. If leap second smearing is not applied, 111 + /// the clock will experience discontinuity around leap second adjustment. 112 + RealTime = bindings::CLOCK_REALTIME, 113 + /// A monotonically increasing clock. 114 + /// 115 + /// A nonsettable system-wide clock that represents monotonic time since—as 116 + /// described by POSIX—"some unspecified point in the past". On Linux, that 117 + /// point corresponds to the number of seconds that the system has been 118 + /// running since it was booted. 119 + /// 120 + /// The CLOCK_MONOTONIC clock is not affected by discontinuous jumps in the 121 + /// CLOCK_REAL (e.g., if the system administrator manually changes the 122 + /// clock), but is affected by frequency adjustments. This clock does not 123 + /// count time that the system is suspended. 124 + Monotonic = bindings::CLOCK_MONOTONIC, 125 + /// A monotonic that ticks while system is suspended. 126 + /// 127 + /// A nonsettable system-wide clock that is identical to CLOCK_MONOTONIC, 128 + /// except that it also includes any time that the system is suspended. This 129 + /// allows applications to get a suspend-aware monotonic clock without 130 + /// having to deal with the complications of CLOCK_REALTIME, which may have 131 + /// discontinuities if the time is changed using settimeofday(2) or similar. 132 + BootTime = bindings::CLOCK_BOOTTIME, 133 + /// International Atomic Time. 134 + /// 135 + /// A system-wide clock derived from wall-clock time but counting leap seconds. 136 + /// 137 + /// This clock is coupled to CLOCK_REALTIME and will be set when CLOCK_REALTIME is 138 + /// set, or when the offset to CLOCK_REALTIME is changed via adjtimex(2). This 139 + /// usually happens during boot and **should** not happen during normal operations. 140 + /// However, if NTP or another application adjusts CLOCK_REALTIME by leap second 141 + /// smearing, this clock will not be precise during leap second smearing. 142 + /// 143 + /// The acronym TAI refers to International Atomic Time. 144 + TAI = bindings::CLOCK_TAI, 145 + } 146 + 147 + impl ClockId { 148 + fn into_c(self) -> bindings::clockid_t { 149 + self as bindings::clockid_t 150 + } 151 + }
+3 -2
rust/kernel/time/hrtimer.rs
··· 67 67 //! A `restart` operation on a timer in the **stopped** state is equivalent to a 68 68 //! `start` operation. 69 69 70 + use super::ClockId; 70 71 use crate::{init::PinInit, prelude::*, time::Ktime, types::Opaque}; 71 72 use core::marker::PhantomData; 72 73 ··· 95 94 96 95 impl<T> HrTimer<T> { 97 96 /// Return an initializer for a new timer instance. 98 - pub fn new(mode: HrTimerMode) -> impl PinInit<Self> 97 + pub fn new(mode: HrTimerMode, clock: ClockId) -> impl PinInit<Self> 99 98 where 100 99 T: HrTimerCallback, 101 100 { ··· 109 108 bindings::hrtimer_setup( 110 109 place, 111 110 Some(T::Pointer::run), 112 - bindings::CLOCK_MONOTONIC as i32, 111 + clock.into_c(), 113 112 mode.into_c(), 114 113 ); 115 114 }