Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'rust-timekeeping-for-v6.16-v2' of https://github.com/Rust-for-Linux/linux into rust-next

Pull timekeeping updates from Andreas Hindborg:

- Morph the Rust hrtimer subsystem into the Rust timekeeping subsystem,
covering delay, sleep, timekeeping, timers. This new subsystem has
all the relevant timekeeping C maintainers listed in the entry.

- Replace 'Ktime' with 'Delta' and 'Instant' types to represent a
duration of time and a point in time.

- Temporarily add 'Ktime' to 'hrtimer' module to allow 'hrtimer' to
delay converting to 'Instant' and 'Delta'.

* tag 'rust-timekeeping-for-v6.16-v2' of https://github.com/Rust-for-Linux/linux:
MAINTAINERS: rust: Add a new section for all of the time stuff
rust: time: Introduce Instant type
rust: time: Introduce Delta type
rust: time: Add PartialEq/Eq/PartialOrd/Ord trait to Ktime
rust: hrtimer: Add Ktime temporarily

+164 -56
+7 -4
MAINTAINERS
··· 10602 10602 F: kernel/time/timer_migration.* 10603 10603 F: tools/testing/selftests/timers/ 10604 10604 10605 - HIGH-RESOLUTION TIMERS [RUST] 10605 + DELAY, SLEEP, TIMEKEEPING, TIMERS [RUST] 10606 10606 M: Andreas Hindborg <a.hindborg@kernel.org> 10607 10607 R: Boqun Feng <boqun.feng@gmail.com> 10608 + R: FUJITA Tomonori <fujita.tomonori@gmail.com> 10608 10609 R: Frederic Weisbecker <frederic@kernel.org> 10609 10610 R: Lyude Paul <lyude@redhat.com> 10610 10611 R: Thomas Gleixner <tglx@linutronix.de> 10611 10612 R: Anna-Maria Behnsen <anna-maria@linutronix.de> 10613 + R: John Stultz <jstultz@google.com> 10614 + R: Stephen Boyd <sboyd@kernel.org> 10612 10615 L: rust-for-linux@vger.kernel.org 10613 10616 S: Supported 10614 10617 W: https://rust-for-linux.com 10615 10618 B: https://github.com/Rust-for-Linux/linux/issues 10616 - T: git https://github.com/Rust-for-Linux/linux.git hrtimer-next 10617 - F: rust/kernel/time/hrtimer.rs 10618 - F: rust/kernel/time/hrtimer/ 10619 + T: git https://github.com/Rust-for-Linux/linux.git timekeeping-next 10620 + F: rust/kernel/time.rs 10621 + F: rust/kernel/time/ 10619 10622 10620 10623 HIGH-SPEED SCC DRIVER FOR AX.25 10621 10624 L: linux-hams@vger.kernel.org
+135 -46
rust/kernel/time.rs
··· 5 5 //! This module contains the kernel APIs related to time and timers that 6 6 //! have been ported or wrapped for usage by Rust code in the kernel. 7 7 //! 8 + //! There are two types in this module: 9 + //! 10 + //! - The [`Instant`] type represents a specific point in time. 11 + //! - The [`Delta`] type represents a span of time. 12 + //! 13 + //! Note that the C side uses `ktime_t` type to represent both. However, timestamp 14 + //! and timedelta are different. To avoid confusion, we use two different types. 15 + //! 16 + //! A [`Instant`] object can be created by calling the [`Instant::now()`] function. 17 + //! It represents a point in time at which the object was created. 18 + //! By calling the [`Instant::elapsed()`] method, a [`Delta`] object representing 19 + //! the elapsed time can be created. The [`Delta`] object can also be created 20 + //! by subtracting two [`Instant`] objects. 21 + //! 22 + //! A [`Delta`] type supports methods to retrieve the duration in various units. 23 + //! 8 24 //! C header: [`include/linux/jiffies.h`](srctree/include/linux/jiffies.h). 9 25 //! C header: [`include/linux/ktime.h`](srctree/include/linux/ktime.h). 10 26 11 27 pub mod hrtimer; 12 28 29 + /// The number of nanoseconds per microsecond. 30 + pub const NSEC_PER_USEC: i64 = bindings::NSEC_PER_USEC as i64; 31 + 13 32 /// The number of nanoseconds per millisecond. 14 33 pub const NSEC_PER_MSEC: i64 = bindings::NSEC_PER_MSEC as i64; 34 + 35 + /// The number of nanoseconds per second. 36 + pub const NSEC_PER_SEC: i64 = bindings::NSEC_PER_SEC as i64; 15 37 16 38 /// The time unit of Linux kernel. One jiffy equals (1/HZ) second. 17 39 pub type Jiffies = crate::ffi::c_ulong; ··· 49 27 unsafe { bindings::__msecs_to_jiffies(msecs) } 50 28 } 51 29 52 - /// A Rust wrapper around a `ktime_t`. 30 + /// A specific point in time. 31 + /// 32 + /// # Invariants 33 + /// 34 + /// The `inner` value is in the range from 0 to `KTIME_MAX`. 53 35 #[repr(transparent)] 54 - #[derive(Copy, Clone)] 55 - pub struct Ktime { 36 + #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord)] 37 + pub struct Instant { 56 38 inner: bindings::ktime_t, 57 39 } 58 40 59 - impl Ktime { 60 - /// Create a `Ktime` from a raw `ktime_t`. 61 - #[inline] 62 - pub fn from_raw(inner: bindings::ktime_t) -> Self { 63 - Self { inner } 64 - } 65 - 41 + impl Instant { 66 42 /// Get the current time using `CLOCK_MONOTONIC`. 67 43 #[inline] 68 - pub fn ktime_get() -> Self { 69 - // SAFETY: It is always safe to call `ktime_get` outside of NMI context. 70 - Self::from_raw(unsafe { bindings::ktime_get() }) 71 - } 72 - 73 - /// Divide the number of nanoseconds by a compile-time constant. 74 - #[inline] 75 - fn divns_constant<const DIV: i64>(self) -> i64 { 76 - self.to_ns() / DIV 77 - } 78 - 79 - /// Returns the number of nanoseconds. 80 - #[inline] 81 - pub fn to_ns(self) -> i64 { 82 - self.inner 83 - } 84 - 85 - /// Returns the number of milliseconds. 86 - #[inline] 87 - pub fn to_ms(self) -> i64 { 88 - self.divns_constant::<NSEC_PER_MSEC>() 89 - } 90 - } 91 - 92 - /// Returns the number of milliseconds between two ktimes. 93 - #[inline] 94 - pub fn ktime_ms_delta(later: Ktime, earlier: Ktime) -> i64 { 95 - (later - earlier).to_ms() 96 - } 97 - 98 - impl core::ops::Sub for Ktime { 99 - type Output = Ktime; 100 - 101 - #[inline] 102 - fn sub(self, other: Ktime) -> Ktime { 44 + pub fn now() -> Self { 45 + // INVARIANT: The `ktime_get()` function returns a value in the range 46 + // from 0 to `KTIME_MAX`. 103 47 Self { 104 - inner: self.inner - other.inner, 48 + // SAFETY: It is always safe to call `ktime_get()` outside of NMI context. 49 + inner: unsafe { bindings::ktime_get() }, 50 + } 51 + } 52 + 53 + /// Return the amount of time elapsed since the [`Instant`]. 54 + #[inline] 55 + pub fn elapsed(&self) -> Delta { 56 + Self::now() - *self 57 + } 58 + } 59 + 60 + impl core::ops::Sub for Instant { 61 + type Output = Delta; 62 + 63 + // By the type invariant, it never overflows. 64 + #[inline] 65 + fn sub(self, other: Instant) -> Delta { 66 + Delta { 67 + nanos: self.inner - other.inner, 105 68 } 106 69 } 107 70 } ··· 154 147 impl ClockId { 155 148 fn into_c(self) -> bindings::clockid_t { 156 149 self as bindings::clockid_t 150 + } 151 + } 152 + 153 + /// A span of time. 154 + /// 155 + /// This struct represents a span of time, with its value stored as nanoseconds. 156 + /// The value can represent any valid i64 value, including negative, zero, and 157 + /// positive numbers. 158 + #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)] 159 + pub struct Delta { 160 + nanos: i64, 161 + } 162 + 163 + impl Delta { 164 + /// A span of time equal to zero. 165 + pub const ZERO: Self = Self { nanos: 0 }; 166 + 167 + /// Create a new [`Delta`] from a number of microseconds. 168 + /// 169 + /// The `micros` can range from -9_223_372_036_854_775 to 9_223_372_036_854_775. 170 + /// If `micros` is outside this range, `i64::MIN` is used for negative values, 171 + /// and `i64::MAX` is used for positive values due to saturation. 172 + #[inline] 173 + pub const fn from_micros(micros: i64) -> Self { 174 + Self { 175 + nanos: micros.saturating_mul(NSEC_PER_USEC), 176 + } 177 + } 178 + 179 + /// Create a new [`Delta`] from a number of milliseconds. 180 + /// 181 + /// The `millis` can range from -9_223_372_036_854 to 9_223_372_036_854. 182 + /// If `millis` is outside this range, `i64::MIN` is used for negative values, 183 + /// and `i64::MAX` is used for positive values due to saturation. 184 + #[inline] 185 + pub const fn from_millis(millis: i64) -> Self { 186 + Self { 187 + nanos: millis.saturating_mul(NSEC_PER_MSEC), 188 + } 189 + } 190 + 191 + /// Create a new [`Delta`] from a number of seconds. 192 + /// 193 + /// The `secs` can range from -9_223_372_036 to 9_223_372_036. 194 + /// If `secs` is outside this range, `i64::MIN` is used for negative values, 195 + /// and `i64::MAX` is used for positive values due to saturation. 196 + #[inline] 197 + pub const fn from_secs(secs: i64) -> Self { 198 + Self { 199 + nanos: secs.saturating_mul(NSEC_PER_SEC), 200 + } 201 + } 202 + 203 + /// Return `true` if the [`Delta`] spans no time. 204 + #[inline] 205 + pub fn is_zero(self) -> bool { 206 + self.as_nanos() == 0 207 + } 208 + 209 + /// Return `true` if the [`Delta`] spans a negative amount of time. 210 + #[inline] 211 + pub fn is_negative(self) -> bool { 212 + self.as_nanos() < 0 213 + } 214 + 215 + /// Return the number of nanoseconds in the [`Delta`]. 216 + #[inline] 217 + pub const fn as_nanos(self) -> i64 { 218 + self.nanos 219 + } 220 + 221 + /// Return the smallest number of microseconds greater than or equal 222 + /// to the value in the [`Delta`]. 223 + #[inline] 224 + pub const fn as_micros_ceil(self) -> i64 { 225 + self.as_nanos().saturating_add(NSEC_PER_USEC - 1) / NSEC_PER_USEC 226 + } 227 + 228 + /// Return the number of milliseconds in the [`Delta`]. 229 + #[inline] 230 + pub const fn as_millis(self) -> i64 { 231 + self.as_nanos() / NSEC_PER_MSEC 157 232 } 158 233 }
+17 -1
rust/kernel/time/hrtimer.rs
··· 68 68 //! `start` operation. 69 69 70 70 use super::ClockId; 71 - use crate::{prelude::*, time::Ktime, types::Opaque}; 71 + use crate::{prelude::*, types::Opaque}; 72 72 use core::marker::PhantomData; 73 73 use pin_init::PinInit; 74 + 75 + /// A Rust wrapper around a `ktime_t`. 76 + // NOTE: Ktime is going to be removed when hrtimer is converted to Instant/Delta. 77 + #[repr(transparent)] 78 + #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord)] 79 + pub struct Ktime { 80 + inner: bindings::ktime_t, 81 + } 82 + 83 + impl Ktime { 84 + /// Returns the number of nanoseconds. 85 + #[inline] 86 + pub fn to_ns(self) -> i64 { 87 + self.inner 88 + } 89 + } 74 90 75 91 /// A timer backed by a C `struct hrtimer`. 76 92 ///
+1 -1
rust/kernel/time/hrtimer/arc.rs
··· 5 5 use super::HrTimerCallback; 6 6 use super::HrTimerHandle; 7 7 use super::HrTimerPointer; 8 + use super::Ktime; 8 9 use super::RawHrTimerCallback; 9 10 use crate::sync::Arc; 10 11 use crate::sync::ArcBorrow; 11 - use crate::time::Ktime; 12 12 13 13 /// A handle for an `Arc<HasHrTimer<T>>` returned by a call to 14 14 /// [`HrTimerPointer::start`].
+1 -1
rust/kernel/time/hrtimer/pin.rs
··· 4 4 use super::HrTimer; 5 5 use super::HrTimerCallback; 6 6 use super::HrTimerHandle; 7 + use super::Ktime; 7 8 use super::RawHrTimerCallback; 8 9 use super::UnsafeHrTimerPointer; 9 - use crate::time::Ktime; 10 10 use core::pin::Pin; 11 11 12 12 /// A handle for a `Pin<&HasHrTimer>`. When the handle exists, the timer might be
+2 -2
rust/kernel/time/hrtimer/pin_mut.rs
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 3 3 use super::{ 4 - HasHrTimer, HrTimer, HrTimerCallback, HrTimerHandle, RawHrTimerCallback, UnsafeHrTimerPointer, 4 + HasHrTimer, HrTimer, HrTimerCallback, HrTimerHandle, Ktime, RawHrTimerCallback, 5 + UnsafeHrTimerPointer, 5 6 }; 6 - use crate::time::Ktime; 7 7 use core::{marker::PhantomData, pin::Pin, ptr::NonNull}; 8 8 9 9 /// A handle for a `Pin<&mut HasHrTimer>`. When the handle exists, the timer might
+1 -1
rust/kernel/time/hrtimer/tbox.rs
··· 5 5 use super::HrTimerCallback; 6 6 use super::HrTimerHandle; 7 7 use super::HrTimerPointer; 8 + use super::Ktime; 8 9 use super::RawHrTimerCallback; 9 10 use crate::prelude::*; 10 - use crate::time::Ktime; 11 11 use core::ptr::NonNull; 12 12 13 13 /// A handle for a [`Box<HasHrTimer<T>>`] returned by a call to