From nobody Tue Nov 26 15:50:04 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3A9061DED4A; Thu, 17 Oct 2024 13:10:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170602; cv=none; b=B6FVk4IAJsP8LU/x+STfOgis89dnkAX/KXQOxnMIjTscrIAJfVwQEyH6xl7KL05IOeai1FQwmQFj8Qx0AWAr9BpPtVtmwiQfDjTLC3yluWAPygHpq/zpY4veJ4QRKjxSOlL2uk27NY0YvO1LalgA7n9KBnGmnntAsTgyNo78o2M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170602; c=relaxed/simple; bh=thj1T8GZG78if/h67vxds3HK/7SEb5HLjMwJifphF9A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Hdj3wcx+VOWOgkx1AV/yReEXO5ByRe7TBg1dbKkGcUvx8kjO8QsIqsHTU7lyqsO5DYxBRjuoD+qVnTzrpq5N96+oBEtjdkd2h+IsmneoQ7sZ1xvi7cf8drkz8xlowhjEEX/8UDHETyALVNVzE2FAWZ8NFrCU2J35hR1UfLy74+Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=sjXHgz3I; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="sjXHgz3I" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6DD88C4CEC3; Thu, 17 Oct 2024 13:09:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1729170600; bh=thj1T8GZG78if/h67vxds3HK/7SEb5HLjMwJifphF9A=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=sjXHgz3I47Fe4Q46fTPIQ624SSSNddSi9yCyXxh5YCvxboAtF7rDfm9knhR5fLlj4 sXEFtn02uVTC/0y2TLjaBVEjZgmh1A1Kgf6+5GK4ZLpcfmFeUJi8GKsmWloBMQfQZE 7jTm6VTtlvzKowIYqDaGB7acXHOKHry9WDDV+Aw6V363eyjjxsGNKRD4lDFMlhh4zn hYNbDjSI3JWlr2agG5OWhP3QvP99eacXnguuuOBH3bWrM0Sr+m6KtpW8lMDNkpAviY iS3pg/4Q9D2QzW91iUWHiK1epVyNryH/b01ceZnVrcnRADiWiP3mS+125VlvXfHvZY mpjHNflgIrbnQ== From: Andreas Hindborg Date: Thu, 17 Oct 2024 15:04:28 +0200 Subject: [PATCH v3 01/13] rust: time: Add Ktime::from_ns() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241017-hrtimer-v3-v6-12-rc2-v3-1-59a75cbb44da@kernel.org> References: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> In-Reply-To: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> To: Miguel Ojeda , Anna-Maria Behnsen , Frederic Weisbecker , Thomas Gleixner Cc: Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Lyude Paul , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.14.2 From: Lyude Paul A simple function to turn the provided value in nanoseconds into a Ktime value. We allow any type which implements Into, which resolves to Into. This is useful for some of the older DRM APIs that never got moved to Ktime Signed-off-by: Lyude Paul Signed-off-by: Andreas Hindborg Reviewed-by: Lyude Paul --- rust/kernel/time.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rust/kernel/time.rs b/rust/kernel/time.rs index e3bb5e89f88dac423e2c0083de8fdfe5ac9a272f..1e02eee09f22b08d4f3ab160e8b= 31b341b5d015c 100644 --- a/rust/kernel/time.rs +++ b/rust/kernel/time.rs @@ -8,6 +8,8 @@ //! C header: [`include/linux/jiffies.h`](srctree/include/linux/jiffies.h). //! C header: [`include/linux/ktime.h`](srctree/include/linux/ktime.h). =20 +use core::convert::Into; + /// The number of nanoseconds per millisecond. pub const NSEC_PER_MSEC: i64 =3D bindings::NSEC_PER_MSEC as i64; =20 @@ -63,6 +65,12 @@ pub fn to_ns(self) -> i64 { pub fn to_ms(self) -> i64 { self.divns_constant::() } + + /// Creates a new Ktime from the given duration in nanoseconds + #[inline] + pub fn from_ns(ns: impl Into) -> Self { + Self { inner: ns.into() } + } } =20 /// Returns the number of milliseconds between two ktimes. --=20 2.46.0 From nobody Tue Nov 26 15:50:04 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 568791DE2AD; Thu, 17 Oct 2024 13:09:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170593; cv=none; b=Fdv6QP+EWExFzFlc84LL+bto/7cle2UUTk/anqjIjHknbgzrQa+RUiL+/8NkRXAElGjSkYAhqgVbpTdvudFtANWLcXk9OEuMYheEDhuyukC+xYtqP4fAgDBMd4MgERpODi8SYl940/WbceD7s3AfrNENy9TSXhHJ8g5wX6zNgYk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170593; c=relaxed/simple; bh=3HeksWAHU84glzjb1XoCrT2n/pqB6Bx/DG1gmiNpkf0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HsYlajp3Y6gIYaNxLeyIUsuXYSVIrppZgBXNyS2N8WV7lHsggm3+hpjh1439TR0QEms5jEdkuMwQgf6ZBKNDM74fZhzWYo8fWNfx/le+C6ct360sAUUFAIJkpGMTGRr4h1JrB1ogqtwWWSWWn/8VhP7VN60nzzsVd1quOc/lXPQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NYzn/uIB; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="NYzn/uIB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 88885C4CEC3; Thu, 17 Oct 2024 13:09:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1729170592; bh=3HeksWAHU84glzjb1XoCrT2n/pqB6Bx/DG1gmiNpkf0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=NYzn/uIBo7wAWmX2olJxsHtU0BpYF922If+2oRwARBAuBGZyPvOJO5b/h3QzJGvKA lYg7YBZEuYHfF8rU4f3iGH7fE7/ra2hmpS3BNWAO/4A7Na5Ngq0VsCSC15iWdhrymi /VOLSUXPn0czyPRUG6jTVdwUS8z+wf68JRuB0eICvbmRk/pM6ZwVkSCZeK6jrPpjHo /kOqqIIaJ05TKRkUadOyA2LDLs1longwVimymGfwLBX1kYcMuNkLtKDLnd/LkdJOKg m61GPSchV1qAqI1QI2uMB5VBxS6G9X4dNfbFhQNOZ/6+gjD3Ncbh7ZmY1f+nHAB0I2 sJkn7nd+3bnCA== From: Andreas Hindborg Date: Thu, 17 Oct 2024 15:04:29 +0200 Subject: [PATCH v3 02/13] rust: hrtimer: introduce hrtimer support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241017-hrtimer-v3-v6-12-rc2-v3-2-59a75cbb44da@kernel.org> References: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> In-Reply-To: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> To: Miguel Ojeda , Anna-Maria Behnsen , Frederic Weisbecker , Thomas Gleixner Cc: Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Lyude Paul , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.14.2 This patch adds support for intrusive use of the hrtimer system. For now, only one timer can be embedded in a Rust struct. The hrtimer Rust API is based on the intrusive style pattern introduced by the Rust workqueue API. Signed-off-by: Andreas Hindborg Reviewed-by: Lyude Paul --- rust/kernel/hrtimer.rs | 304 +++++++++++++++++++++++++++++++++++++++++++++= ++++ rust/kernel/lib.rs | 1 + 2 files changed, 305 insertions(+) diff --git a/rust/kernel/hrtimer.rs b/rust/kernel/hrtimer.rs new file mode 100644 index 0000000000000000000000000000000000000000..99058a690f2e18b5c26c94c7113= 3407019aa4a26 --- /dev/null +++ b/rust/kernel/hrtimer.rs @@ -0,0 +1,304 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Intrusive high resolution timers. +//! +//! Allows running timer callbacks without doing allocations at the time of +//! starting the timer. For now, only one timer per type is allowed. +//! +//! # Vocabulary +//! +//! A timer is initialized in the **stopped** state. A stopped timer can be +//! **started** with an **expiry** time. After the timer is started, it is +//! **running**. When the timer **expires**, the timer handler is executed. +//! After the handler has executed, the timer may be **restarted** or +//! **stopped**. A running timer can be **cancelled** before it's handler = is +//! executed. A timer that is cancelled enters the **stopped** state. +//! +//! States: +//! +//! * Stopped +//! * Running +//! +//! Operations: +//! +//! * Start +//! * Cancel +//! * Stop +//! * Restart +//! +//! Events: +//! +//! * Expire + +use crate::{init::PinInit, prelude::*, time::Ktime, types::Opaque}; +use core::marker::PhantomData; + +/// A timer backed by a C `struct hrtimer`. +/// +/// # Invariants +/// +/// * `self.timer` is initialized by `bindings::hrtimer_init`. +#[repr(transparent)] +#[pin_data] +#[repr(C)] +pub struct Timer { + #[pin] + timer: Opaque, + _t: PhantomData, +} + +// SAFETY: A `Timer` can be moved to other threads and used/dropped from t= here. +unsafe impl Send for Timer {} + +// SAFETY: Timer operations are locked on C side, so it is safe to operate= on a +// timer from multiple threads +unsafe impl Sync for Timer {} + +impl Timer { + /// Return an initializer for a new timer instance. + pub fn new() -> impl PinInit + where + T: TimerCallback, + { + pin_init!(Self { + // INVARIANTS: We initialize `timer` with `hrtimer_init` below. + timer <- Opaque::ffi_init(move |place: *mut bindings::hrtimer|= { + // SAFETY: By design of `pin_init!`, `place` is a pointer = live + // allocation. hrtimer_init will initialize `place` and do= es not + // require `place` to be initialized prior to the call. + unsafe { + bindings::hrtimer_init( + place, + bindings::CLOCK_MONOTONIC as i32, + bindings::hrtimer_mode_HRTIMER_MODE_REL, + ); + } + + // SAFETY: `place` is pointing to a live allocation, so th= e deref + // is safe. + let function =3D + unsafe { core::ptr::addr_of_mut!((*place).function) }; + + // SAFETY: `function` points to a valid allocation and we = have + // exclusive access. + unsafe { core::ptr::write(function, Some(T::CallbackTarget= ::run)) }; + }), + _t: PhantomData, + }) + } + + /// Get a pointer to the contained `bindings::hrtimer`. + /// + /// # Safety + /// + /// `ptr` must point to a live allocation of at least the size of `Sel= f`. + unsafe fn raw_get(ptr: *const Self) -> *mut bindings::hrtimer { + // SAFETY: The field projection to `timer` does not go out of boun= ds, + // because the caller of this function promises that `ptr` points = to an + // allocation of at least the size of `Self`. + unsafe { Opaque::raw_get(core::ptr::addr_of!((*ptr).timer)) } + } + + /// Cancel an initialized and potentially running timer. + /// + /// If the timer handler is running, this will block until the handler= is + /// finished. + /// + /// # Safety + /// + /// `self_ptr` must point to a valid `Self`. + #[allow(dead_code)] + pub(crate) unsafe fn raw_cancel(self_ptr: *const Self) -> bool { + // SAFETY: timer_ptr points to an allocation of at least `Timer` s= ize. + let c_timer_ptr =3D unsafe { Timer::raw_get(self_ptr) }; + + // If handler is running, this will wait for handler to finish bef= ore + // returning. + // SAFETY: `c_timer_ptr` is initialized and valid. Synchronization= is + // handled on C side. + unsafe { bindings::hrtimer_cancel(c_timer_ptr) !=3D 0 } + } +} + +/// Implemented by pointer types that point to structs that embed a [`Time= r`]. +/// +/// Typical implementers would be [`Box`], [`Arc`], [`ARef`] wher= e `T` +/// has a field of type `Timer`. +/// +/// Target must be [`Sync`] because timer callbacks happen in another thre= ad of +/// execution (hard or soft interrupt context). +/// +/// Starting a timer returns a [`TimerHandle`] that can be used to manipul= ate +/// the timer. Note that it is OK to call the start function repeatedly, a= nd +/// that more than one [`TimerHandle`] associated with a `TimerPointer` may +/// exist. A timer can be manipulated through any of the handles, and a ha= ndle +/// may represent a cancelled timer. +/// +/// [`Box`]: Box +/// [`Arc`]: crate::sync::Arc +/// [`ARef`]: crate::types::ARef +pub trait TimerPointer: Sync + Sized { + /// A handle representing a running timer. + /// + /// If the timer is running or if the timer callback is executing when= the + /// handle is dropped, the drop method of `TimerHandle` should not ret= urn + /// until the timer is stopped and the callback has completed. + /// + /// Note: It must be safe to leak the handle. + type TimerHandle: TimerHandle; + + /// Start the timer with expiry after `expires` time units. If the tim= er was + /// already running, it is restarted with the new expiry time. + fn start(self, expires: Ktime) -> Self::TimerHandle; +} + +/// Implemented by [`TimerPointer`] implementers to give the C timer callb= ack a +/// function to call. +// This is split from `TimerPointer` to make it easier to specify trait bo= unds. +pub trait RawTimerCallback { + /// Callback to be called from C when timer fires. + /// + /// # Safety + /// + /// Only to be called by C code in `hrtimer` subsystem. `ptr` must poi= nt to + /// the `bindings::hrtimer` structure that was used to start the timer. + unsafe extern "C" fn run(ptr: *mut bindings::hrtimer) -> bindings::hrt= imer_restart; +} + +/// Implemented by structs that can the target of a timer callback. +pub trait TimerCallback { + /// The type that was used for starting the timer. + type CallbackTarget<'a>: RawTimerCallback; + + /// This type is passed to the timer callback function. It may be a bo= rrow + /// of [`Self::CallbackTarget`], or it may be `Self::CallbackTarget` i= f the + /// implementation can guarantee exclusive access to the target during= timer + /// handler execution. + type CallbackTargetParameter<'a>; + + /// Called by the timer logic when the timer fires. + fn run(this: Self::CallbackTargetParameter<'_>) + where + Self: Sized; +} + +/// A handle representing a potentially running timer. +/// +/// More than one handle representing the same timer might exist. +/// +/// # Safety +/// +/// When dropped, the timer represented by this handle must be cancelled, = if it +/// is running. If the timer handler is running when the handle is dropped= , the +/// drop method must wait for the handler to finish before returning. +pub unsafe trait TimerHandle { + /// Cancel the timer, if it is running. If the timer handler is runnin= g, block + /// till the handler has finished. + fn cancel(&mut self) -> bool; +} + +/// Implemented by structs that contain timer nodes. +/// +/// Clients of the timer API would usually safely implement this trait by = using +/// the [`impl_has_timer`] macro. +/// +/// # Safety +/// +/// Implementers of this trait must ensure that the implementer has a [`Ti= mer`] +/// field at the offset specified by `OFFSET` and that all trait methods a= re +/// implemented according to their documentation. +/// +/// [`impl_has_timer`]: crate::impl_has_timer +pub unsafe trait HasTimer { + /// Offset of the [`Timer`] field within `Self` + const OFFSET: usize; + + /// Return a pointer to the [`Timer`] within `Self`. + /// + /// # Safety + /// + /// `ptr` must point to a valid struct of type `Self`. + unsafe fn raw_get_timer(ptr: *const Self) -> *const Timer { + // SAFETY: By the safety requirement of this trait, the trait + // implementor will have a `Timer` field at the specified offset. + unsafe { ptr.cast::().add(Self::OFFSET).cast::>() } + } + + /// Return a pointer to the struct that is embedding the [`Timer`] poi= nted + /// to by `ptr`. + /// + /// # Safety + /// + /// `ptr` must point to a [`Timer`] field in a struct of type `Self= `. + unsafe fn timer_container_of(ptr: *mut Timer) -> *mut Self + where + Self: Sized, + { + // SAFETY: By the safety requirement of this function and the `Has= Timer` + // trait, the following expression will yield a pointer to the `Se= lf` + // containing the timer addressed by `ptr`. + unsafe { ptr.cast::().sub(Self::OFFSET).cast::() } + } + + /// Get pointer to embedded `bindings::hrtimer` struct. + /// + /// # Safety + /// + /// `self_ptr` must point to a valid `Self`. + unsafe fn c_timer_ptr(self_ptr: *const Self) -> *const bindings::hrtim= er { + // SAFETY: `self_ptr` is a valid pointer to a `Self`. + let timer_ptr =3D unsafe { Self::raw_get_timer(self_ptr) }; + + // SAFETY: timer_ptr points to an allocation of at least `Timer` s= ize. + unsafe { Timer::raw_get(timer_ptr) } + } + + /// Start the timer contained in the `Self` pointed to by `self_ptr`. = If + /// it is already running it is removed and inserted. + /// + /// # Safety + /// + /// `self_ptr` must point to a valid `Self`. + unsafe fn start(self_ptr: *const Self, expires: Ktime) { + unsafe { + bindings::hrtimer_start_range_ns( + Self::c_timer_ptr(self_ptr).cast_mut(), + expires.to_ns(), + 0, + bindings::hrtimer_mode_HRTIMER_MODE_REL, + ); + } + } +} + +/// Use to implement the [`HasTimer`] trait. +/// +/// See [`module`] documentation for an example. +/// +/// [`module`]: crate::hrtimer +#[macro_export] +macro_rules! impl_has_timer { + ( + impl$({$($generics:tt)*})? + HasTimer<$timer_type:ty> + for $self:ty + { self.$field:ident } + $($rest:tt)* + ) =3D> { + // SAFETY: This implementation of `raw_get_timer` only compiles if= the + // field has the right type. + unsafe impl$(<$($generics)*>)? $crate::hrtimer::HasTimer<$timer_ty= pe> for $self { + const OFFSET: usize =3D ::core::mem::offset_of!(Self, $field) = as usize; + + #[inline] + unsafe fn raw_get_timer(ptr: *const Self) -> + *const $crate::hrtimer::Timer<$timer_type> + { + // SAFETY: The caller promises that the pointer is not dan= gling. + unsafe { + ::core::ptr::addr_of!((*ptr).$field) + } + } + } + } +} diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index b5f4b3ce6b48203507f89bcc4b0bf7b076be6247..d21c6afc50a9dd35d33829252d3= cf320e4244864 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -34,6 +34,7 @@ pub mod error; #[cfg(CONFIG_RUST_FW_LOADER_ABSTRACTIONS)] pub mod firmware; +pub mod hrtimer; pub mod init; pub mod ioctl; #[cfg(CONFIG_KUNIT)] --=20 2.46.0 From nobody Tue Nov 26 15:50:04 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 44ED51DE882; Thu, 17 Oct 2024 13:09:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170569; cv=none; b=WMjAF4/GfyHgugzVVYhQcp7muXHc5uKFCd79L9gbps+WANQ00UKLmrLcPKnaTUD26qRytq6DyL/rWhmKRAcUSbOgNHnM0GWZiQIktOMBpLxifI1WaQVcxk1KPhnHvgM9w2wdBW/K0Rjr6KP71hwSeLos+UnImotyx+s44kSA2tw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170569; c=relaxed/simple; bh=5C2sQwreJAUq2xkupKtASZ31n79IvjHwew9MiqdV2gQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QJo9qZnNVOWAHVES07ivKDfdyUmB9V34J/ggaz2ndum8RCPpb+Qow6gKJKcs0EzW+vjr+JoPGjvFoDZ+vtlpA38FMDt6HvJVDZSXdcyEVzTIbj4KEEM4MOX/8HuePoGnUgqUN8l8dzyMBpUuaJBV7V53KlD+evD1T0VZh3H/HFY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=k03efsGw; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="k03efsGw" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 613FEC4CEC3; Thu, 17 Oct 2024 13:09:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1729170568; bh=5C2sQwreJAUq2xkupKtASZ31n79IvjHwew9MiqdV2gQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=k03efsGwkAOdspzTf41oAKUSZenaZH4FETcsJiTM8AuGa/GF+y5Qg93qg8F+L4BjT YA1ADPcPDbkV5RG6KAeHC8u/u7fSRpjwHq1SmmXMGxiOMb++81jqiPNlWxxlHiwcvF t5jjdUnGiCgBBfGJmHJEVAPdAkD2QUgFMX1NN66KTAaz5cEDyVtteylkWXMVQe4Mez OGXSfj5EBqEfY4+ZPQqlo5h7FlKfpk0Bwdfeu8yqMsg7JhHmRp3GPlvZPQSesxBQ+o 3FCSCFoUhBaIiGtuieOatsNv+a/6HoIlRNVTXaG1kIIIN1Q6RBm65khw3LZf7Vjsxv RUmB6R0GiOhCA== From: Andreas Hindborg Date: Thu, 17 Oct 2024 15:04:30 +0200 Subject: [PATCH v3 03/13] rust: sync: add `Arc::as_ptr` Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241017-hrtimer-v3-v6-12-rc2-v3-3-59a75cbb44da@kernel.org> References: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> In-Reply-To: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> To: Miguel Ojeda , Anna-Maria Behnsen , Frederic Weisbecker , Thomas Gleixner Cc: Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Lyude Paul , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.14.2 Add a method to get a pointer to the data contained in an `Arc`. Signed-off-by: Andreas Hindborg Reviewed-by: Lyude Paul --- rust/kernel/sync/arc.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs index 3021f30fd822f6a59c33f32e08008c7fea483b02..5e73af1253df37c2c810a0ee6f1= b1236bbddef5e 100644 --- a/rust/kernel/sync/arc.rs +++ b/rust/kernel/sync/arc.rs @@ -237,6 +237,15 @@ pub fn into_raw(self) -> *const T { unsafe { core::ptr::addr_of!((*ptr).data) } } =20 + /// Return a raw pointer to the data in this arc. + pub fn as_ptr(this: &Self) -> *const T { + let ptr =3D this.ptr.as_ptr(); + + // SAFETY: As `ptr` points to a valid allocation of type `ArcInner= `, + // field projection to `data`is within bounds of the allocation. + unsafe { core::ptr::addr_of!((*ptr).data) } + } + /// Recreates an [`Arc`] instance previously deconstructed via [`Arc::= into_raw`]. /// /// # Safety @@ -515,11 +524,11 @@ unsafe fn new(inner: NonNull>) -> Self { } =20 /// Creates an [`ArcBorrow`] to an [`Arc`] that has previously been de= constructed with - /// [`Arc::into_raw`]. + /// [`Arc::into_raw`] or [`Arc::as_ptr`]. /// /// # Safety /// - /// * The provided pointer must originate from a call to [`Arc::into_r= aw`]. + /// * The provided pointer must originate from a call to [`Arc::into_r= aw`] or [`Arc::as_ptr`]. /// * For the duration of the lifetime annotated on this `ArcBorrow`, = the reference count must /// not hit zero. /// * For the duration of the lifetime annotated on this `ArcBorrow`, = there must not be a --=20 2.46.0 From nobody Tue Nov 26 15:50:04 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8A60C1DE4C8; Thu, 17 Oct 2024 13:09:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170560; cv=none; b=uzsvCLGrzZFoBYqRgRBd76JrjY28XGWiPLW1bVMqrSz93g9nxJiRppvcdNZNZ2t3pSRiwg+CXoX1nWvDhPnmbobR/6gL/GbVIHepUbcPxqlOHeG/MP1I+Ubon2r28pVT7HhNPgWkB9+DM5ry60/h37MnGlIOHuLneVAd6G5YmF8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170560; c=relaxed/simple; bh=kEEtRzguOzN8Ion4HyzOjI+aWeQ2Y+lQGVZV/cNGGmg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AxwqSlyQeZyoVBftBsOharVkottOGNCNdr5c+2Zy/jmGMz9eim38ClpzruXQ9y9V08fOprUvWX3+MA/Na3v38UeAS932GW2OfgMsqRo+wTldAhD4Mcu09ve7lX8KrS+0rfrTTG2ZKYpkDXUi/syuImZcAS4xd8LPcwgQZdYtqOI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=uPV/MUyT; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="uPV/MUyT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DB6D9C4CEC5; Thu, 17 Oct 2024 13:09:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1729170560; bh=kEEtRzguOzN8Ion4HyzOjI+aWeQ2Y+lQGVZV/cNGGmg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=uPV/MUyT34OMZaTRj+PVZ3QpMZt4s/DmIGXQvou6Ly/plWJuykg+0DNzcFJjNwouz zlk+0GDYu3hUVJwWKDE4JM5ZAiA8kPuA2R07gWKbnqz85kW1MYXdOuFHiYIRNxan57 dQlbxBYmgB0mnK1CvYPj643uAu8MLw7mO1vL4av+EVOq+K1XcdLm84Pm8UAVP4UW9E P5xd0HqAf1HY1dP52OOk1z8ayWZHEQsKFputT+3/pA1ZHNjyqdoQ0jeiveQOVhHcow PYiwmvFlgRPjl5Dg+FbxRC6eALkMAoVAL5ADwKSDre14yoCjH2YiCigzYmMlFzluY3 oID++KAqIRztg== From: Andreas Hindborg Date: Thu, 17 Oct 2024 15:04:31 +0200 Subject: [PATCH v3 04/13] rust: hrtimer: implement `TimerPointer` for `Arc` Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241017-hrtimer-v3-v6-12-rc2-v3-4-59a75cbb44da@kernel.org> References: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> In-Reply-To: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> To: Miguel Ojeda , Anna-Maria Behnsen , Frederic Weisbecker , Thomas Gleixner Cc: Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Lyude Paul , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.14.2 This patch allows the use of intrusive `hrtimer` fields in structs that are managed by an `Arc`. Signed-off-by: Andreas Hindborg Reviewed-by: Lyude Paul --- rust/kernel/hrtimer.rs | 3 +- rust/kernel/hrtimer/arc.rs | 89 ++++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/rust/kernel/hrtimer.rs b/rust/kernel/hrtimer.rs index 99058a690f2e18b5c26c94c71133407019aa4a26..6427b0450c694105190c8cddea0= c768ab195aca2 100644 --- a/rust/kernel/hrtimer.rs +++ b/rust/kernel/hrtimer.rs @@ -107,7 +107,6 @@ unsafe fn raw_get(ptr: *const Self) -> *mut bindings::h= rtimer { /// # Safety /// /// `self_ptr` must point to a valid `Self`. - #[allow(dead_code)] pub(crate) unsafe fn raw_cancel(self_ptr: *const Self) -> bool { // SAFETY: timer_ptr points to an allocation of at least `Timer` s= ize. let c_timer_ptr =3D unsafe { Timer::raw_get(self_ptr) }; @@ -302,3 +301,5 @@ unsafe fn raw_get_timer(ptr: *const Self) -> } } } + +mod arc; diff --git a/rust/kernel/hrtimer/arc.rs b/rust/kernel/hrtimer/arc.rs new file mode 100644 index 0000000000000000000000000000000000000000..881de053ecad866a26e46a0123e= c2bf38511c2bc --- /dev/null +++ b/rust/kernel/hrtimer/arc.rs @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0 + +use super::HasTimer; +use super::RawTimerCallback; +use super::Timer; +use super::TimerCallback; +use super::TimerHandle; +use super::TimerPointer; +use crate::sync::Arc; +use crate::sync::ArcBorrow; +use crate::time::Ktime; + +/// A handle for an `Arc>` returned by a call to +/// [`TimerPointer::start`]. +pub struct ArcTimerHandle +where + U: HasTimer, +{ + pub(crate) inner: Arc, +} + +// SAFETY: We implement drop below, and we cancel the timer in the drop +// implementation. +unsafe impl TimerHandle for ArcTimerHandle +where + U: HasTimer, +{ + fn cancel(&mut self) -> bool { + let self_ptr =3D Arc::as_ptr(&self.inner); + + // SAFETY: As we obtained `self_ptr` from a valid reference above,= it + // must point to a valid `U`. + let timer_ptr =3D unsafe { >::raw_get_timer(self_= ptr) }; + + // SAFETY: As `timer_ptr` points into `U` and `U` is valid, `timer= _ptr` + // must point to a valid `Timer` instance. + unsafe { Timer::::raw_cancel(timer_ptr) } + } +} + +impl Drop for ArcTimerHandle +where + U: HasTimer, +{ + fn drop(&mut self) { + self.cancel(); + } +} + +impl TimerPointer for Arc +where + U: Send + Sync, + U: HasTimer, + U: for<'a> TimerCallback =3D Self>, +{ + type TimerHandle =3D ArcTimerHandle; + + fn start(self, expires: Ktime) -> ArcTimerHandle { + // SAFETY: Since we generate the pointer passed to `start` from a + // valid reference, it is a valid pointer. + unsafe { U::start(Arc::as_ptr(&self), expires) }; + + ArcTimerHandle { inner: self } + } +} + +impl RawTimerCallback for Arc +where + U: HasTimer, + U: for<'a> TimerCallback =3D Self>, + U: for<'a> TimerCallback =3D ArcBorrow<'a,= U>>, +{ + unsafe extern "C" fn run(ptr: *mut bindings::hrtimer) -> bindings::hrt= imer_restart { + // `Timer` is `repr(C)` + let timer_ptr =3D ptr.cast::>(); + + // SAFETY: By C API contract `ptr` is the pointer we passed when + // queuing the timer, so it is a `Timer` embedded in a `T`. + let data_ptr =3D unsafe { U::timer_container_of(timer_ptr) }; + + // SAFETY: `data_ptr` points to the `U` that was used to queue the + // timer. This `U` is contained in an `Arc`. + let receiver =3D unsafe { ArcBorrow::from_raw(data_ptr) }; + + U::run(receiver); + + bindings::hrtimer_restart_HRTIMER_NORESTART + } +} --=20 2.46.0 From nobody Tue Nov 26 15:50:04 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 151631DE2AD; Thu, 17 Oct 2024 13:09:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170589; cv=none; b=mUAGrRuV0vtlD3oK/2Z/siEKH8lK0DdNqApz4Q3JmlU7XduC1faefOLKqtcxVYlX/MR8CZSUskIjs0jg+3D/RQi5rPvclt+pqSN7XSvZyS2IXCvcz1a+DoKhDS34Hs4yH6SkMOE4CSUZ5+cMk4RpYBJW3y1mW/ZZZVLYmTKDDOg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170589; c=relaxed/simple; bh=5K0yiQ3f26xg0MDHhzbmwWVR37a+DzYwHtFeTLTca1k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=a+rwLottZEiaazHC+oTl/8y2tzwKStLY30GRkFPeMymWKtzEW1/bznbLIJ+vExVde54vfIMa5m8RBL9h+me0T7tAqOp1zxFSr7KFn19rGwyi5/dAFzohZ7bnI4FOXONkFvUHDD/sTwoHsLbP9J4yy+bdq+6sl5CtX4GjK4Vr2wo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=XdvHDHcC; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="XdvHDHcC" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 72765C4CEC3; Thu, 17 Oct 2024 13:09:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1729170588; bh=5K0yiQ3f26xg0MDHhzbmwWVR37a+DzYwHtFeTLTca1k=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=XdvHDHcC2qFBDxhuvVWplIb0PNKti6pP3/674B+02Ato/qYJ+RChxQfjb2Ummqhtq 5TI8nk4RnR9J8z2RvP5AijDfZCxS43UgpRcFtJNcxGqY7WjVEnwDkX397Lph4unwFp GpX4h+BJmj5q8OrhWI5x0j8Zcg/89nN5tR1/S4lVs7kHmbvt3QHYlPA3ajiwQu2O3n 4JnxwxxGJSDYzR9HXziYdqK0UpySxTGFnVyt7NamQExf9kN9yqcGBMCyUdtH9zXPWR lmBDP/5Td6LTPYbMlD/k0m6E/rx0vU3muxf0rIyk3FNWZV2lfycc8iNjIrt+H2XZRs lRnjHsHSG0FrQ== From: Andreas Hindborg Date: Thu, 17 Oct 2024 15:04:32 +0200 Subject: [PATCH v3 05/13] rust: hrtimer: allow timer restart from timer handler Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241017-hrtimer-v3-v6-12-rc2-v3-5-59a75cbb44da@kernel.org> References: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> In-Reply-To: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> To: Miguel Ojeda , Anna-Maria Behnsen , Frederic Weisbecker , Thomas Gleixner Cc: Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Lyude Paul , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.14.2 This patch allows timer handlers to report that they want a timer to be restarted after the timer handler has finished executing. Also update the `hrtimer` documentation to showcase the new feature. Signed-off-by: Andreas Hindborg Reviewed-by: Lyude Paul --- rust/kernel/hrtimer.rs | 28 +++++++++++++++++++++++++++- rust/kernel/hrtimer/arc.rs | 4 +--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/rust/kernel/hrtimer.rs b/rust/kernel/hrtimer.rs index 6427b0450c694105190c8cddea0c768ab195aca2..eeed2afd501b64b94d57cc65861= 6659e28785078 100644 --- a/rust/kernel/hrtimer.rs +++ b/rust/kernel/hrtimer.rs @@ -176,7 +176,7 @@ pub trait TimerCallback { type CallbackTargetParameter<'a>; =20 /// Called by the timer logic when the timer fires. - fn run(this: Self::CallbackTargetParameter<'_>) + fn run(this: Self::CallbackTargetParameter<'_>) -> TimerRestart where Self: Sized; } @@ -270,6 +270,32 @@ unsafe fn start(self_ptr: *const Self, expires: Ktime)= { } } =20 +/// Restart policy for timers. +pub enum TimerRestart { + /// Timer should not be restarted. + NoRestart, + /// Timer should be restarted. + Restart, +} + +impl From for TimerRestart { + fn from(value: bindings::hrtimer_restart) -> Self { + match value { + 0 =3D> Self::NoRestart, + _ =3D> Self::Restart, + } + } +} + +impl From for bindings::hrtimer_restart { + fn from(value: TimerRestart) -> Self { + match value { + TimerRestart::NoRestart =3D> bindings::hrtimer_restart_HRTIMER= _NORESTART, + TimerRestart::Restart =3D> bindings::hrtimer_restart_HRTIMER_R= ESTART, + } + } +} + /// Use to implement the [`HasTimer`] trait. /// /// See [`module`] documentation for an example. diff --git a/rust/kernel/hrtimer/arc.rs b/rust/kernel/hrtimer/arc.rs index 881de053ecad866a26e46a0123ec2bf38511c2bc..c6283bd0dbb10dbc733c3f4092f= 107db2f3c5c5f 100644 --- a/rust/kernel/hrtimer/arc.rs +++ b/rust/kernel/hrtimer/arc.rs @@ -82,8 +82,6 @@ impl RawTimerCallback for Arc // timer. This `U` is contained in an `Arc`. let receiver =3D unsafe { ArcBorrow::from_raw(data_ptr) }; =20 - U::run(receiver); - - bindings::hrtimer_restart_HRTIMER_NORESTART + U::run(receiver).into() } } --=20 2.46.0 From nobody Tue Nov 26 15:50:04 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 286351DE8A6; Thu, 17 Oct 2024 13:09:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170582; cv=none; b=s5rkXOz7arCpoy7n9rNployWJXE3qvpkJAy++Cpt/PXllTRvgF/S9dIhjRkKR9gsbYc3KOb8BTdMi7dx7xaxtb5S0bwA6GizElpaLbLfpZ5fcT/Nkhz444lQWBIe2DUDdPvOm6HTEcDk/L6HULGEaDte3RlEU66qURZZki2kz+I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170582; c=relaxed/simple; bh=BwgOBAi5yShmdWTwzvNb4FXstAurI+WiBcPUMOK/JIo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lzyDZ3p8xBp99N7s2lte69+Vu2iVsV/jNBBj7VEnxEKYR/Bsb86TxFHRmLexVtlBrsJCXvqQcxWCpsWqDaqKm1JLC+yx66YjuAAl1PYAyMuIsnABhU5shBhtpG0VPDTrYBXrvs01hih/3p3ob1pwCDxOUApAQrpkEiEYR3aUUuQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WsofrX/E; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="WsofrX/E" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 75731C4CEC3; Thu, 17 Oct 2024 13:09:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1729170580; bh=BwgOBAi5yShmdWTwzvNb4FXstAurI+WiBcPUMOK/JIo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=WsofrX/EaHtbdH1OJXFOvbZ9Xog1OIC5OzzBQKA9fSZKCySsbg2TtGT2rRZiAgWr7 s7TppwDrkllyrh80V7r640hVwSl2YiBNl/FUckwkZE8fM8MrcyWHs4CVRNoPAcoSI5 ioawsHljkKSkOmIuxKKL7iNn9/MpGqFzPlvSTEm4pCpkDjLp1xZko4l2DDbSP5AjPd D8nshqg78D5xZBanTKy6xGxrjPRUDk8hIvqEN5PXw90xJQMh7p49UiX+y3fKuuGcH3 SXpL9Vt6FhPIKB/dvWsevy4AgC6SNGdHowV5Cd2YWIIQvyR5isZBM/b1t1r0BuPDH2 jTy7aPYaddt+A== From: Andreas Hindborg Date: Thu, 17 Oct 2024 15:04:33 +0200 Subject: [PATCH v3 06/13] rust: hrtimer: add `UnsafeTimerPointer` Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241017-hrtimer-v3-v6-12-rc2-v3-6-59a75cbb44da@kernel.org> References: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> In-Reply-To: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> To: Miguel Ojeda , Anna-Maria Behnsen , Frederic Weisbecker , Thomas Gleixner Cc: Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Lyude Paul , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.14.2 Add a trait to allow unsafely queuing stack allocated timers. Signed-off-by: Andreas Hindborg Reviewed-by: Lyude Paul --- rust/kernel/hrtimer.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/rust/kernel/hrtimer.rs b/rust/kernel/hrtimer.rs index eeed2afd501b64b94d57cc658616659e28785078..e97d7b8ec63ce6c9ac3fe952219= 2a28fba78b8ba 100644 --- a/rust/kernel/hrtimer.rs +++ b/rust/kernel/hrtimer.rs @@ -151,6 +151,39 @@ pub trait TimerPointer: Sync + Sized { fn start(self, expires: Ktime) -> Self::TimerHandle; } =20 +/// Unsafe version of [`TimerPointer`] for situations where leaking the +/// `TimerHandle` returned by `start` would be unsound. This is the case f= or +/// stack allocated timers. +/// +/// Typical implementers are pinned references such as [`Pin<&T>]. +/// +/// # Safety +/// +/// Implementers of this trait must ensure that instances of types impleme= nting +/// [`UnsafeTimerPointer`] outlives any associated [`TimerPointer::TimerHa= ndle`] +/// instances. +/// +/// [`Pin<&T>`]: Box +pub unsafe trait UnsafeTimerPointer: Sync + Sized { + /// A handle representing a running timer. + /// + /// # Safety + /// + /// If the timer is running, or if the timer callback is executing whe= n the + /// handle is dropped, the drop method of `TimerHandle` must not return + /// until the timer is stopped and the callback has completed. + type TimerHandle: TimerHandle; + + /// Start the timer after `expires` time units. If the timer was alrea= dy + /// running, it is restarted at the new expiry time. + /// + /// # Safety + /// + /// Caller promises keep the timer structure alive until the timer is = dead. + /// Caller can ensure this by not leaking the returned `Self::TimerHan= dle`. + unsafe fn start(self, expires: Ktime) -> Self::TimerHandle; +} + /// Implemented by [`TimerPointer`] implementers to give the C timer callb= ack a /// function to call. // This is split from `TimerPointer` to make it easier to specify trait bo= unds. --=20 2.46.0 From nobody Tue Nov 26 15:50:04 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B0B641DD55F; Thu, 17 Oct 2024 13:09:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170548; cv=none; b=UmxkulIKEywpFaH3aIEG49k2qB4+SmexxRy72xAm5yCx50FWzOY1CUGfcTMOr7cYZzZfTiRsfsLDyZZXU+7viON9It1BNFMV043Yik6qT8Eyn3OFuB42HCyN0eS8eOse6ID1W3hMEtooDoyDjIsAiQv6Nv4f6v7lRnHBnmM/spY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170548; c=relaxed/simple; bh=djeIObyYMSba/ry9C1XpjcUIkMvUsOg5eoyYeIu/FVk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pWlU3nnxdJMwBOeyxRmkSp0AB3zUH3jg27bKdO1sR9Y/OJpX1ZBTxgaTSWYcy9NjVd3Lmm6hGqCQb6gkJs7mY1E7bl/Mu0UV8Bs7M/0jY+65StruhripFMUNfPZD9LK64AGldkowNmhotoncAIvcI//CapH5F2WSkCV76g5wJbE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MyMl5eer; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MyMl5eer" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D45B3C4CED1; Thu, 17 Oct 2024 13:09:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1729170548; bh=djeIObyYMSba/ry9C1XpjcUIkMvUsOg5eoyYeIu/FVk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=MyMl5eer7cUrJYaPmR8C+qCyZikwe3X7j6fVSgW5dw+Q1lmPRjU9k0NVgukzpYxle 7nOMPjGGC07wjcY5+t0qFR/kdnxICQNr76qyGnB5nbhd7xfDW5N+GYzgSVBc5tyJgL bYegPriCSzmdaEFn2zTYkRKZRtM5Roqz3OhhcluH5sYj+SIlLJ95jJ7MvTBhu/vtNM EjYGXiUNJPwP6J1QoBsNJIquZFB86VsWZmsA+0ekVZXlWaU88/9JMQmO9w+03S+8xO D8JO+3OAGUXxUpZFU/+s1sLobfSg+db8FuGmyFvS0g90XwWDETBwG+yTpo2eF7UVdZ uuQ0HA3/av7WQ== From: Andreas Hindborg Date: Thu, 17 Oct 2024 15:04:34 +0200 Subject: [PATCH v3 07/13] rust: hrtimer: implement `UnsafeTimerPointer` for `Pin<&T>` Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241017-hrtimer-v3-v6-12-rc2-v3-7-59a75cbb44da@kernel.org> References: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> In-Reply-To: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> To: Miguel Ojeda , Anna-Maria Behnsen , Frederic Weisbecker , Thomas Gleixner Cc: Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Lyude Paul , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.14.2 Allow pinned references to structs that contain a `Timer` node to be scheduled with the `hrtimer` subsystem. Signed-off-by: Andreas Hindborg Reviewed-by: Lyude Paul --- rust/kernel/hrtimer.rs | 1 + rust/kernel/hrtimer/pin.rs | 97 ++++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 98 insertions(+) diff --git a/rust/kernel/hrtimer.rs b/rust/kernel/hrtimer.rs index e97d7b8ec63ce6c9ac3fe9522192a28fba78b8ba..ceedf330a803ec2db7ff6c25713= ae48e2fd1f4ca 100644 --- a/rust/kernel/hrtimer.rs +++ b/rust/kernel/hrtimer.rs @@ -362,3 +362,4 @@ unsafe fn raw_get_timer(ptr: *const Self) -> } =20 mod arc; +mod pin; diff --git a/rust/kernel/hrtimer/pin.rs b/rust/kernel/hrtimer/pin.rs new file mode 100644 index 0000000000000000000000000000000000000000..a2c1dbd5e48b668cc3dc540c5fd= 5514f5331d968 --- /dev/null +++ b/rust/kernel/hrtimer/pin.rs @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0 + +use super::HasTimer; +use super::RawTimerCallback; +use super::Timer; +use super::TimerCallback; +use super::TimerHandle; +use super::UnsafeTimerPointer; +use crate::time::Ktime; +use core::pin::Pin; + +/// A handle for a `Pin<&HasTimer>`. When the handle exists, the timer mig= ht be +/// running. +pub struct PinTimerHandle<'a, U> +where + U: HasTimer, +{ + pub(crate) inner: Pin<&'a U>, +} + +// SAFETY: We cancel the timer when the handle is dropped. The implementat= ion of +// the `cancel` method will block if the timer handler is running. +unsafe impl<'a, U> TimerHandle for PinTimerHandle<'a, U> +where + U: HasTimer, +{ + fn cancel(&mut self) -> bool { + let self_ptr =3D self.inner.get_ref() as *const U; + + // SAFETY: As we got `self_ptr` from a reference above, it must po= int to + // a valid `U`. + let timer_ptr =3D unsafe { >::raw_get_timer(self_= ptr) }; + + // SAFETY: As `timer_ptr` is derived from a reference, it must poi= nt to + // a valid and initialized `Timer`. + unsafe { Timer::::raw_cancel(timer_ptr) } + } +} + +impl<'a, U> Drop for PinTimerHandle<'a, U> +where + U: HasTimer, +{ + fn drop(&mut self) { + self.cancel(); + } +} + +// SAFETY: We capture the lifetime of `Self` when we create a `PinTimerHan= dle`, +// so `Self` will outlive the handle. +unsafe impl<'a, U> UnsafeTimerPointer for Pin<&'a U> +where + U: Send + Sync, + U: HasTimer, + U: TimerCallback =3D Self>, +{ + type TimerHandle =3D PinTimerHandle<'a, U>; + + unsafe fn start(self, expires: Ktime) -> Self::TimerHandle { + use core::ops::Deref; + + // Cast to pointer + let self_ptr =3D self.deref() as *const U; + + // SAFETY: As we derive `self_ptr` from a reference above, it must= point + // to a valid `U`. + unsafe { U::start(self_ptr, expires) }; + + PinTimerHandle { inner: self } + } +} + +impl<'a, U> RawTimerCallback for Pin<&'a U> +where + U: HasTimer, + U: TimerCallback =3D Self>, + U: TimerCallback =3D Self>, +{ + unsafe extern "C" fn run(ptr: *mut bindings::hrtimer) -> bindings::hrt= imer_restart { + // `Timer` is `repr(C)` + let timer_ptr =3D ptr as *mut Timer; + + // SAFETY: By the safety requirement of this function, `timer_ptr` + // points to a `Timer` contained in an `U`. + let receiver_ptr =3D unsafe { U::timer_container_of(timer_ptr) }; + + // SAFETY: By the safety requirement of this function, `timer_ptr` + // points to a `Timer` contained in an `U`. + let receiver_ref =3D unsafe { &*receiver_ptr }; + + // SAFETY: `receiver_ref` only exists as pinned, so it is safe to = pin it + // here. + let receiver_pin =3D unsafe { Pin::new_unchecked(receiver_ref) }; + + U::run(receiver_pin).into() + } +} --=20 2.46.0 From nobody Tue Nov 26 15:50:04 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3A6571DE893; Thu, 17 Oct 2024 13:09:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170577; cv=none; b=GptpORyyMeVyl052m5tNVO6vPEgp8CHCZQi5rnnAypvhONsLYswpUE2OGQquupG01JaucycCh84MhQi6RIhMVpcHtiImfhgI9ScHMQZJyrO+1jaKOrLA784NeiRHNM7JJlKdroZtnBKPPaVmpv25MY/9YrQAWmiRDV+eh+majTA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170577; c=relaxed/simple; bh=vK66/laxxraODLHeUfQy6EIVcT/80ojUgOWDCBSGJcs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CvTW+EexXtwulsZ142icJXRyiM1B6srLxkOA3/P+KiNePCN+vVDkrRI7Chl0RZITLDl0B8tJSiJnNiB/jLr/DwTrMSigPUOWeCoS5jTtXuM8alZ7bUq5oROUcQ2ttAruBL1wFerljo/cDmBieYTfFb9CuEv2HXz2hxErjccyiz0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nXikI7Q/; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="nXikI7Q/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6A1E1C4CEC3; Thu, 17 Oct 2024 13:09:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1729170576; bh=vK66/laxxraODLHeUfQy6EIVcT/80ojUgOWDCBSGJcs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=nXikI7Q/iXtSUChiZjg5VM2V6SbDL1EWfPtcYI9l3xuc0MD5mIqkK7Dew/Tt11qDI KQJDa7RnGN9o6Df22UyGYTYza654ur8duVzUBEgGuxtg2Lwxug3Rc/wwn/F0Lj7A/0 HhpBxgRPon2vt/trsLXM8KFDoJYV+/rwIomWS6YdgoHUf2K4x5vBkeVJ1pt7bUjyP1 yEF4JpaLN9962Y3XWYnygBQGoaLydooyRDTjM+QSxzRe+DKd/H2Fyz8tcTmKVgIWA2 HhbGPy5fjcEjeQIzB7igFcQrseMiQNVDI+QEpLahT9Yut7fzYS2JZThTpC/2TnXMWw cw8y1fNyZ/sqQ== From: Andreas Hindborg Date: Thu, 17 Oct 2024 15:04:35 +0200 Subject: [PATCH v3 08/13] rust: hrtimer: implement `UnsafeTimerPointer` for `Pin<&mut T>` Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241017-hrtimer-v3-v6-12-rc2-v3-8-59a75cbb44da@kernel.org> References: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> In-Reply-To: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> To: Miguel Ojeda , Anna-Maria Behnsen , Frederic Weisbecker , Thomas Gleixner Cc: Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Lyude Paul , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.14.2 Allow pinned mutable references to structs that contain a `Timer` node to be scheduled with the `hrtimer` subsystem. Signed-off-by: Andreas Hindborg Reviewed-by: Lyude Paul --- rust/kernel/hrtimer.rs | 1 + rust/kernel/hrtimer/pin_mut.rs | 99 ++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 100 insertions(+) diff --git a/rust/kernel/hrtimer.rs b/rust/kernel/hrtimer.rs index ceedf330a803ec2db7ff6c25713ae48e2fd1f4ca..940390aa2a6c6a222534b545d8d= 2fbd639a19f64 100644 --- a/rust/kernel/hrtimer.rs +++ b/rust/kernel/hrtimer.rs @@ -363,3 +363,4 @@ unsafe fn raw_get_timer(ptr: *const Self) -> =20 mod arc; mod pin; +mod pin_mut; diff --git a/rust/kernel/hrtimer/pin_mut.rs b/rust/kernel/hrtimer/pin_mut.rs new file mode 100644 index 0000000000000000000000000000000000000000..d6c85647a762066776cf292620a= 8b19c12721876 --- /dev/null +++ b/rust/kernel/hrtimer/pin_mut.rs @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0 + +use super::HasTimer; +use super::RawTimerCallback; +use super::Timer; +use super::TimerCallback; +use super::TimerHandle; +use super::UnsafeTimerPointer; +use crate::time::Ktime; +use core::pin::Pin; + +/// A handle for a `Pin<&mut HasTimer>`. When the handle exists, the timer= might +/// be running. +pub struct PinMutTimerHandle<'a, U> +where + U: HasTimer, +{ + pub(crate) inner: Pin<&'a mut U>, +} + +// SAFETY: We cancel the timer when the handle is dropped. The implementat= ion of +// the `cancel` method will block if the timer handler is running. +unsafe impl<'a, U> TimerHandle for PinMutTimerHandle<'a, U> +where + U: HasTimer, +{ + fn cancel(&mut self) -> bool { + // SAFETY: We are not moving out of `self` or handing out mutable + // references to `self`. + let self_ptr =3D unsafe { self.inner.as_mut().get_unchecked_mut() = as *mut U }; + + // SAFETY: As we got `self_ptr` from a reference above, it must po= int to + // a valid `U`. + let timer_ptr =3D unsafe { >::raw_get_timer(self_= ptr) }; + + // SAFETY: As `timer_ptr` is derived from a reference, it must poi= nt to + // a valid and initialized `Timer`. + unsafe { Timer::::raw_cancel(timer_ptr) } + } +} + +impl<'a, U> Drop for PinMutTimerHandle<'a, U> +where + U: HasTimer, +{ + fn drop(&mut self) { + self.cancel(); + } +} + +// SAFETY: We capture the lifetime of `Self` when we create a +// `PinMutTimerHandle`, so `Self` will outlive the handle. +unsafe impl<'a, U> UnsafeTimerPointer for Pin<&'a mut U> +where + U: Send + Sync, + U: HasTimer, + U: TimerCallback =3D Self>, +{ + type TimerHandle =3D PinMutTimerHandle<'a, U>; + + unsafe fn start(self, expires: Ktime) -> Self::TimerHandle { + use core::ops::Deref; + + // Cast to pointer + let self_ptr =3D self.deref() as *const U; + + // SAFETY: As we derive `self_ptr` from a reference above, it must= point + // to a valid `U`. + unsafe { U::start(self_ptr, expires) }; + + PinMutTimerHandle { inner: self } + } +} + +impl<'a, U> RawTimerCallback for Pin<&'a mut U> +where + U: HasTimer, + U: TimerCallback =3D Self>, + U: TimerCallback =3D Self>, +{ + unsafe extern "C" fn run(ptr: *mut bindings::hrtimer) -> bindings::hrt= imer_restart { + // `Timer` is `repr(C)` + let timer_ptr =3D ptr as *mut Timer; + + // SAFETY: By the safety requirement of this function, `timer_ptr` + // points to a `Timer` contained in an `U`. + let receiver_ptr =3D unsafe { U::timer_container_of(timer_ptr) }; + + // SAFETY: By the safety requirement of this function, `timer_ptr` + // points to a `Timer` contained in an `U`. + let receiver_ref =3D unsafe { &mut *receiver_ptr }; + + // SAFETY: `receiver_ref` only exists as pinned, so it is safe to = pin it + // here. + let receiver_pin =3D unsafe { Pin::new_unchecked(receiver_ref) }; + + U::run(receiver_pin).into() + } +} --=20 2.46.0 From nobody Tue Nov 26 15:50:04 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3E7E31DE8AB; Thu, 17 Oct 2024 13:09:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170585; cv=none; b=ZmIeAGn/lktXycgzlWKW6llpc8gb550fj9ba4Fv+4RBb2W+qBpDCadHd3lKSD8yzPUNFukiVuycYrKGjpni05oVgE70q7C3Loe8k02TYbQiqItIFvzCZUi/V7zx+ZDpcnCi7yxOsd8W3DnAY3TwguuL4XNBKaCbkhYJB57P0ahE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170585; c=relaxed/simple; bh=ubHMqwiCJXg9dE3U2XZY1Btul8vxT790+NI8IDvfJuU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sBFDhGBLlW3PIUfwo24JYFGdS0J2SgAhg8G+NUpCroe+nTQFH2nKF6sVxAzLiNNk1s93fq5yJP1G0y1aOW8H1Jk8jX2AI7ak583Z+HCvrpE+lEqnkIZTSYuuzyqmqBoVTy3byD8OPUgyyXmVAWKDJnkzAdCAIh2bbivv3HzoXME= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Mq+pY+/L; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Mq+pY+/L" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 73EA0C4CEC5; Thu, 17 Oct 2024 13:09:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1729170584; bh=ubHMqwiCJXg9dE3U2XZY1Btul8vxT790+NI8IDvfJuU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Mq+pY+/LTrq/w9pHX6cpZV5ibbpxS1npFZ19lxdGDdXV7cxH7KMDr0Udi03gZecqR drwGS5D4Nks8gLROMjg10vVDt9EV6xMLm0L6moGXMR3nShVKIm6LlidZtJzUVWX5PH V14q0NcArZUPAz2T5aTxjoUNKhSCxMgezQBEXD+r+gNC9n9X7OL8/8i3vjIg2EdIV1 JilrQ7Uf6xAjuuWBBBmwbP+SvUnsuxLXtJ/E+LW255pHqV8cL/1bJYYSd3rznbh5pQ 9gSF7DKo6PdkP8aXsdZlBPjDi0zN/0BmgesJ2hq4x4lrl9VyNExv4qSy02hzrdGKcZ x0SnS99kh5teg== From: Andreas Hindborg Date: Thu, 17 Oct 2024 15:04:36 +0200 Subject: [PATCH v3 09/13] rust: hrtimer: add `hrtimer::ScopedTimerPointer` Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241017-hrtimer-v3-v6-12-rc2-v3-9-59a75cbb44da@kernel.org> References: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> In-Reply-To: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> To: Miguel Ojeda , Anna-Maria Behnsen , Frederic Weisbecker , Thomas Gleixner Cc: Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Lyude Paul , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.14.2 Add the trait `ScopedTimerPointer` to allow safe use of stack allocated timers. Safety is achieved by pinning the stack in place while timers are running. Implement the trait for all types that implement `UnsafeTimerPointer`. Signed-off-by: Andreas Hindborg Reviewed-by: Lyude Paul --- rust/kernel/hrtimer.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/rust/kernel/hrtimer.rs b/rust/kernel/hrtimer.rs index 940390aa2a6c6a222534b545d8d2fbd639a19f64..d8cea8b15a9afc134b10dc5703d= 88d70323fc943 100644 --- a/rust/kernel/hrtimer.rs +++ b/rust/kernel/hrtimer.rs @@ -184,6 +184,39 @@ pub unsafe trait UnsafeTimerPointer: Sync + Sized { unsafe fn start(self, expires: Ktime) -> Self::TimerHandle; } =20 +/// A trait for stack allocated timers. +/// +/// # Safety +/// +/// Implementers must ensure that `start_scoped` does not return until the +/// timer is dead and the timer handler is not running. +pub unsafe trait ScopedTimerPointer { + /// Start the timer to run after `expires` time units and immediately + /// after call `f`. When `f` returns, the timer is cancelled. + fn start_scoped(self, expires: Ktime, f: F) -> T + where + F: FnOnce() -> T; +} + +// SAFETY: By the safety requirement of `UnsafeTimerPointer`, dropping the +// handle returned by [`UnsafeTimerPointer::start`] ensures that the timer= is +// killed. +unsafe impl ScopedTimerPointer for U +where + U: UnsafeTimerPointer, +{ + fn start_scoped(self, expires: Ktime, f: F) -> T + where + F: FnOnce() -> T, + { + // SAFETY: We drop the timer handle below before returning. + let handle =3D unsafe { UnsafeTimerPointer::start(self, expires) }; + let t =3D f(); + drop(handle); + t + } +} + /// Implemented by [`TimerPointer`] implementers to give the C timer callb= ack a /// function to call. // This is split from `TimerPointer` to make it easier to specify trait bo= unds. --=20 2.46.0 From nobody Tue Nov 26 15:50:04 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D584F1DF73E; Thu, 17 Oct 2024 13:09:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170596; cv=none; b=KkplE+30ihRlI2KOT2gUfImQUfGrWiqD5OiynF0GTaAz9f+WUoDfkGutCnxF9pzmTong8of9SLL8cUlK/vsnub9EegzSjhpm8rKTKhQ1M1xjWGa/pH03aDlPYTCuNY76cXtWEo98yc4EHqK7u0nsr5GUFo4+NguGa91Zm7AhFRY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170596; c=relaxed/simple; bh=WpykfoidvT7YgqobFCGhM6E4/3XnNpFURLVGB8L0/r4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QxVQ80A7lWj8tMWNOmO3iDKqQ1aNLtYVuyWYaxO0tDMuPBf/pkxgS4L5tl4fdgXKXiBKdPIDn1ozeIk3ONIO/8nI2276Exy+Y1k0WDoHPlqYnJaDqYW6APM+dg7tfIoQUZyRuSX6au89fp2TOlQ7ijDIVV+0XZd96zjaWApl5sg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ivv5H52c; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ivv5H52c" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7E7FDC4CEC3; Thu, 17 Oct 2024 13:09:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1729170596; bh=WpykfoidvT7YgqobFCGhM6E4/3XnNpFURLVGB8L0/r4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ivv5H52clVpqohzUraSFqFMKtx5OdPvKNwPoOyk5lkUnrn3gWYDcoINV1uBSJIW5v d4C9vZx1aUu8MX5dSkzAv7rQBhvnlY0iUrbeWUIXin4eTqVOVnr5FX5yh9F5RUhrkx cNs48OAtrwUJqhqd+cqzawD5cNo5uiYTg+jRuzURLCJyEvI0epdG9U6Uks2Or5bvUl mf9RdnQnhYO0heOyayLNMAfC1ihg5d2+JczTpzHWfro6oINdjqxDHuzsMc3Kf2NiCj Bxx7pT+9h3rBdqhyRU4rpayGU6HK0dHdJwwyiuG89SG3iedBquK7EgbU6e3EydMpz3 QEGMHC9HFbWBA== From: Andreas Hindborg Date: Thu, 17 Oct 2024 15:04:37 +0200 Subject: [PATCH v3 10/13] rust: hrtimer: implement `TimerPointer` for `Pin>` Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241017-hrtimer-v3-v6-12-rc2-v3-10-59a75cbb44da@kernel.org> References: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> In-Reply-To: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> To: Miguel Ojeda , Anna-Maria Behnsen , Frederic Weisbecker , Thomas Gleixner Cc: Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Lyude Paul , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.14.2 Allow `Pin>` to be the target of a timer callback. Signed-off-by: Andreas Hindborg Reviewed-by: Lyude Paul --- rust/kernel/hrtimer.rs | 3 ++ rust/kernel/hrtimer/tbox.rs | 95 +++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 98 insertions(+) diff --git a/rust/kernel/hrtimer.rs b/rust/kernel/hrtimer.rs index d8cea8b15a9afc134b10dc5703d88d70323fc943..2c1573e19576de93afc959d71e9= 4173e2c1ed715 100644 --- a/rust/kernel/hrtimer.rs +++ b/rust/kernel/hrtimer.rs @@ -394,6 +394,9 @@ unsafe fn raw_get_timer(ptr: *const Self) -> } } =20 +// `box` is a reserved keyword, so prefix with `t` for timer +mod tbox; + mod arc; mod pin; mod pin_mut; diff --git a/rust/kernel/hrtimer/tbox.rs b/rust/kernel/hrtimer/tbox.rs new file mode 100644 index 0000000000000000000000000000000000000000..b4199671d728c7f070b4ffb30a3= cbc2635c0cb89 --- /dev/null +++ b/rust/kernel/hrtimer/tbox.rs @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0 + +use super::HasTimer; +use super::RawTimerCallback; +use super::Timer; +use super::TimerCallback; +use super::TimerHandle; +use super::TimerPointer; +use crate::prelude::*; +use crate::time::Ktime; +use core::mem::ManuallyDrop; + +/// A handle for a `Box>` returned by a call to +/// [`TimerPointer::start`]. +pub struct BoxTimerHandle +where + U: HasTimer, +{ + pub(crate) inner: *mut U, +} + +// SAFETY: We implement drop below, and we cancel the timer in the drop +// implementation. +unsafe impl TimerHandle for BoxTimerHandle +where + U: HasTimer, +{ + fn cancel(&mut self) -> bool { + // SAFETY: As we obtained `self.inner` from a valid reference when= we + // created `self`, it must point to a valid `U`. + let timer_ptr =3D unsafe { >::raw_get_timer(self.= inner) }; + + // SAFETY: As `timer_ptr` points into `U` and `U` is valid, `timer= _ptr` + // must point to a valid `Timer` instance. + unsafe { Timer::::raw_cancel(timer_ptr) } + } +} + +impl Drop for BoxTimerHandle +where + U: HasTimer, +{ + fn drop(&mut self) { + self.cancel(); + } +} + +impl TimerPointer for Pin> +where + U: Send + Sync, + U: HasTimer, + U: for<'a> TimerCallback =3D Pin>>, + U: for<'a> TimerCallback =3D Pin<&'a U>>, +{ + type TimerHandle =3D BoxTimerHandle; + + fn start(self, expires: Ktime) -> Self::TimerHandle { + use core::ops::Deref; + let self_ptr =3D self.deref() as *const U; + + // SAFETY: Since we generate the pointer passed to `start` from a = valid + // reference, it is a valid pointer. + unsafe { U::start(self_ptr, expires) }; + + // SAFETY: We will not move out of this box during timer callback = (we + // pass an immutable reference to the callback). + let inner =3D unsafe { Pin::into_inner_unchecked(self) }; + + BoxTimerHandle { + inner: Box::into_raw(inner), + } + } +} + +impl RawTimerCallback for Pin> +where + U: HasTimer, + U: for<'a> TimerCallback =3D Pin>>, + U: for<'a> TimerCallback =3D Pin<&'a U>>, +{ + unsafe extern "C" fn run(ptr: *mut bindings::hrtimer) -> bindings::hrt= imer_restart { + // `Timer` is `repr(C)` + let timer_ptr =3D ptr.cast::>(); + + // SAFETY: By C API contract `ptr` is the pointer we passed when + // queuing the timer, so it is a `Timer` embedded in a `T`. + let data_ptr =3D unsafe { U::timer_container_of(timer_ptr) }; + + // SAFETY: We called `Box::into_raw` when we queued the timer. + let tbox =3D ManuallyDrop::new(Box::into_pin(unsafe { Box::from_ra= w(data_ptr) })); + + use core::ops::Deref; + U::run(tbox.deref().as_ref()).into() + } +} --=20 2.46.0 From nobody Tue Nov 26 15:50:04 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CF7441DE2A2; Thu, 17 Oct 2024 13:09:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170572; cv=none; b=HI1beb668qvHoRe7gWNdnxcg42rMMJYBdpeovlMENkJX/AZIovSxsbKb2vvPiIwiMdQ6aikFMLTPf83z1olOOzIqXi07Xkcw5LZ56bkYLiHbanc6DM0XpstsNbORUno8krgnfuiqIt/8t0z8m5Pz9t7G1S5BuzTUReH3ud+ZkKE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170572; c=relaxed/simple; bh=6GsQsOXBkEeRY13Q8KtQu/O5wn3Kj6oFTmpBitQUMoI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=N9lQsdJ5N14e8M/vj6dHnj2ASRkV4jfsiiRliqL7zUbXAj7bcaJ4e6yi1VzsWwrdRa00lG0H2SEko4Vcc1SQxn0M6QDH3nklR6S0bgjnNSlkGNNjQqQ55hHRug2bnoexBk/5bCGfc6y6RTomSsdBbp2BymJeDqw4idLFqnSO5uY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BVpJiZeN; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BVpJiZeN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5FB57C4CEC5; Thu, 17 Oct 2024 13:09:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1729170572; bh=6GsQsOXBkEeRY13Q8KtQu/O5wn3Kj6oFTmpBitQUMoI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=BVpJiZeNfa+o7sXwgZhU/9TajP1Ho6+dkU72SJ9Piji006YANwQIRbWBaeWOLaRMu eq71CQszVoXWUZF5Iw75MkzMhCNJItO3oPq1L+7OONkcUG+apb2vZOz/wystMrPIO/ TV0GVq7U9pcWfzPdvgH64zNviZ7nnT5QzimwtiJMDCO4jHUa5mcDNAaNO+1vgC19Va ZZXrcPCBgoWlpBVFg/8/ukpIgo0hXOAZQLZmnlQo8SqSAJgWrjkVt/iyDU3YmYsGCe LJrg/cgc1qbgBqkliGMfS1fVlolYIv3suvkoQeCw32grzHWRx1GXcCuy3ThM+vl1DV RbVtf6Xb2oHOg== From: Andreas Hindborg Date: Thu, 17 Oct 2024 15:04:38 +0200 Subject: [PATCH v3 11/13] rust: hrtimer: add `TimerMode` Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241017-hrtimer-v3-v6-12-rc2-v3-11-59a75cbb44da@kernel.org> References: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> In-Reply-To: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> To: Miguel Ojeda , Anna-Maria Behnsen , Frederic Weisbecker , Thomas Gleixner Cc: Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Lyude Paul , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.14.2 Allow selection of timer mode by passing a `TimerMode` variant to `Timer::new`. Signed-off-by: Andreas Hindborg Reviewed-by: Lyude Paul --- rust/kernel/hrtimer.rs | 88 ++++++++++++++++++++++++++++++++++++++++++++++= +--- 1 file changed, 84 insertions(+), 4 deletions(-) diff --git a/rust/kernel/hrtimer.rs b/rust/kernel/hrtimer.rs index 2c1573e19576de93afc959d71e94173e2c1ed715..1674d1dcba39cc7ab82e1f18900= 2afa365ee9341 100644 --- a/rust/kernel/hrtimer.rs +++ b/rust/kernel/hrtimer.rs @@ -38,12 +38,13 @@ /// # Invariants /// /// * `self.timer` is initialized by `bindings::hrtimer_init`. -#[repr(transparent)] #[pin_data] #[repr(C)] pub struct Timer { #[pin] timer: Opaque, + // This field goes away when `bindings::hrtimer_setup` is added. + mode: TimerMode, _t: PhantomData, } =20 @@ -56,7 +57,7 @@ unsafe impl Sync for Timer {} =20 impl Timer { /// Return an initializer for a new timer instance. - pub fn new() -> impl PinInit + pub fn new(mode: TimerMode) -> impl PinInit where T: TimerCallback, { @@ -70,7 +71,7 @@ pub fn new() -> impl PinInit bindings::hrtimer_init( place, bindings::CLOCK_MONOTONIC as i32, - bindings::hrtimer_mode_HRTIMER_MODE_REL, + mode.into(), ); } =20 @@ -83,6 +84,7 @@ pub fn new() -> impl PinInit // exclusive access. unsafe { core::ptr::write(function, Some(T::CallbackTarget= ::run)) }; }), + mode: mode, _t: PhantomData, }) } @@ -330,7 +332,7 @@ unsafe fn start(self_ptr: *const Self, expires: Ktime) { Self::c_timer_ptr(self_ptr).cast_mut(), expires.to_ns(), 0, - bindings::hrtimer_mode_HRTIMER_MODE_REL, + (*Self::raw_get_timer(self_ptr)).mode.into(), ); } } @@ -362,6 +364,84 @@ fn from(value: TimerRestart) -> Self { } } =20 +/// Operational mode of [`Timer`]. +#[derive(Clone, Copy)] +pub enum TimerMode { + /// Timer expires at the given expiration time. + Absolute, + /// Timer expires after the given expiration time interpreted as a dur= ation 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 dur= ation 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 dur= ation 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 dur= ation 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 dur= ation 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 dur= ation from now. + /// Timer does not move between CPU cores. + /// Timer handler is executed in hard irq context. + RelativePinnedHard, +} + +impl From for bindings::hrtimer_mode { + fn from(value: TimerMode) -> Self { + use bindings::*; + match value { + TimerMode::Absolute =3D> hrtimer_mode_HRTIMER_MODE_ABS, + TimerMode::Relative =3D> hrtimer_mode_HRTIMER_MODE_REL, + TimerMode::Pinned =3D> hrtimer_mode_HRTIMER_MODE_PINNED, + TimerMode::Soft =3D> hrtimer_mode_HRTIMER_MODE_SOFT, + TimerMode::Hard =3D> hrtimer_mode_HRTIMER_MODE_HARD, + TimerMode::AbsolutePinned =3D> hrtimer_mode_HRTIMER_MODE_ABS_P= INNED, + TimerMode::RelativePinned =3D> hrtimer_mode_HRTIMER_MODE_REL_P= INNED, + TimerMode::AbsoluteSoft =3D> hrtimer_mode_HRTIMER_MODE_ABS_SOF= T, + TimerMode::RelativeSoft =3D> hrtimer_mode_HRTIMER_MODE_REL_SOF= T, + TimerMode::AbsolutePinnedSoft =3D> hrtimer_mode_HRTIMER_MODE_A= BS_PINNED_SOFT, + TimerMode::RelativePinnedSoft =3D> hrtimer_mode_HRTIMER_MODE_R= EL_PINNED_SOFT, + TimerMode::AbsoluteHard =3D> hrtimer_mode_HRTIMER_MODE_ABS_HAR= D, + TimerMode::RelativeHard =3D> hrtimer_mode_HRTIMER_MODE_REL_HAR= D, + TimerMode::AbsolutePinnedHard =3D> hrtimer_mode_HRTIMER_MODE_A= BS_PINNED_HARD, + TimerMode::RelativePinnedHard =3D> hrtimer_mode_HRTIMER_MODE_R= EL_PINNED_HARD, + } + } +} + +impl From for u64 { + fn from(value: TimerMode) -> Self { + Into::::into(value) as u64 + } +} + /// Use to implement the [`HasTimer`] trait. /// /// See [`module`] documentation for an example. --=20 2.46.0 From nobody Tue Nov 26 15:50:04 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9A6EC1DE3A5; Thu, 17 Oct 2024 13:09:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170557; cv=none; b=E+iz6DzQkT20Imx6qi1A3jJ6oxOBjaHE5a3u1XXzWvbIW1u2ADThUVNNW8cgidUjMLcgJa8d+jEgy7OONFB19XdKn7B7+lWSRwLJv6JcL74yLtPgJxue0QzPQU4QSGtvuwHZjYxuJDi8lc4aFLwPFVONujJMQKtfX0iukAzeIkg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170557; c=relaxed/simple; bh=pcbBSEOaYdDpx4xhl+4Ai8sZ4IvENt0icA1nT6MrNCA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=isaZD7c1FB1tJZpYV2WKPkW54Hm462tsierLjEHnCwGsPt9VKLvb8BkAmBGYgLoAoe2DnalU2Y+sPjg26bhPKR7jp98KOqEPwRXCL4uMKhmeGzEtxJURyeGSxZuNEd/O4pNunKHHNo5Dj66OjNtulJNTbgD3u/UuTLQeq+N4gJg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kD3KUHVh; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="kD3KUHVh" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 01C79C4CEC3; Thu, 17 Oct 2024 13:09:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1729170556; bh=pcbBSEOaYdDpx4xhl+4Ai8sZ4IvENt0icA1nT6MrNCA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=kD3KUHVh1tofmIpCByHH3oddeWbvkLdMkum2LWq8sdmJ+yYLxqe0KKVR+kEaFAccS 8wWpktZT1qHbkCsszGLjlnNjtivdPnI6egPdrWBK253LO99mPOFooajIygeQW5ebl/ caWSr4k6PpF3eQLayCtFBKdPLWT9lIYdYWXymX1N5wcMHcj/GLTRC00kaP7XnM0U0x K2Zgke8mjLIMxHbaMfqzcvl0eIBUT3eMrOQAwkzzp+kAqnV1fwk5msqz5TLpY/eh/I MFxgkYBT1/FlVeW7ccYH9RdfFLruEtJUNJeU9rNtA6r3Ybxu3sdr0qFXl0eWLVLj6O Dmw2erjDutTUQ== From: Andreas Hindborg Date: Thu, 17 Oct 2024 15:04:39 +0200 Subject: [PATCH v3 12/13] rust: hrtimer: add clocksource selection through `ClockSource` Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241017-hrtimer-v3-v6-12-rc2-v3-12-59a75cbb44da@kernel.org> References: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> In-Reply-To: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> To: Miguel Ojeda , Anna-Maria Behnsen , Frederic Weisbecker , Thomas Gleixner Cc: Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Lyude Paul , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.14.2 Allow selecting a clock source for timers by passing a `ClockSource` variant to `Timer::new`. Signed-off-by: Andreas Hindborg Reviewed-by: Lyude Paul --- rust/kernel/hrtimer.rs | 52 ++++++++++++++++++++++++++++++++++++++++++++++= ++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/rust/kernel/hrtimer.rs b/rust/kernel/hrtimer.rs index 1674d1dcba39cc7ab82e1f189002afa365ee9341..f3d57c6cb1a95075c28192b5cd2= f97431989a0b1 100644 --- a/rust/kernel/hrtimer.rs +++ b/rust/kernel/hrtimer.rs @@ -57,7 +57,7 @@ unsafe impl Sync for Timer {} =20 impl Timer { /// Return an initializer for a new timer instance. - pub fn new(mode: TimerMode) -> impl PinInit + pub fn new(mode: TimerMode, clock: ClockSource) -> impl PinInit where T: TimerCallback, { @@ -70,7 +70,7 @@ pub fn new(mode: TimerMode) -> impl PinInit unsafe { bindings::hrtimer_init( place, - bindings::CLOCK_MONOTONIC as i32, + clock.into(), mode.into(), ); } @@ -442,6 +442,54 @@ fn from(value: TimerMode) -> Self { } } =20 +/// The clock source to use for a [`Timer`]. +pub enum ClockSource { + /// A settable system-wide clock that measures real (i.e., wall-clock)= time. + /// Setting this clock requires appropriate privileges. This clock is + /// affected by discontinuous jumps in the system time (e.g., if the s= ystem + /// administrator manually changes the clock), and by frequency adjust= ments + /// performed by NTP and similar applications via adjtime(3), adjtimex= (2), + /// clock_adjtime(2), and ntp_adjtime(3). This clock normally counts t= he + /// number of seconds since 1970-01-01 00:00:00 Coordinated Universal = Time + /// (UTC) except that it ignores leap seconds; near a leap second it is + /// typically adjusted by NTP to stay roughly in sync with UTC. + RealTime, + /// A nonsettable system-wide clock that represents monotonic time sin= ce=E2=80=94as + /// described by POSIX=E2=80=94"some unspecified point in the past". O= n Linux, that + /// point corresponds to the number of seconds that the system has been + /// running since it was booted. + /// + /// The CLOCK_MONOTONIC clock is not affected by discontinuous jumps i= n the + /// system time (e.g., if the system administrator manually changes the + /// clock), but is affected by frequency adjustments. This clock does = not + /// count time that the system is suspended. + Monotonic, + /// A nonsettable system-wide clock that is identical to CLOCK_MONOTON= IC, + /// except that it also includes any time that the system is suspended= . This + /// allows applications to get a suspend-aware monotonic clock without + /// having to deal with the complications of CLOCK_REALTIME, which may= have + /// discontinuities if the time is changed using settimeofday(2) or si= milar. + BootTime, + /// A nonsettable system-wide clock derived from wall-clock time but + /// counting leap seconds. This clock does not experience discontinuit= ies or + /// frequency adjustments caused by inserting leap seconds as CLOCK_RE= ALTIME + /// does. + /// + /// The acronym TAI refers to International Atomic Time. + TAI, +} + +impl From for bindings::clockid_t { + fn from(value: ClockSource) -> Self { + match value { + ClockSource::RealTime =3D> bindings::CLOCK_REALTIME as i32, + ClockSource::Monotonic =3D> bindings::CLOCK_MONOTONIC as i32, + ClockSource::BootTime =3D> bindings::CLOCK_BOOTTIME as i32, + ClockSource::TAI =3D> bindings::CLOCK_TAI as i32, + } + } +} + /// Use to implement the [`HasTimer`] trait. /// /// See [`module`] documentation for an example. --=20 2.46.0 From nobody Tue Nov 26 15:50:04 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CCDC31DE3A5; Thu, 17 Oct 2024 13:09:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170552; cv=none; b=ES1zdgWYSgYqeSdrObQD6EKykCdVRcUESW78GH//gcsq6dYsAqNIRgJeCZXvpDIhd8nLy+TOcv4DmpUIWc5xafGTQaaYT8k7i4lDxiQ7abHOorFOArzM6XH/iHNbhOKh7hJdyIswr9p3bVDCvlP0ENIY9a8Pyf8JvXABiDtq6Hw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729170552; c=relaxed/simple; bh=qzP2YzXKrnzveGOYctsIdkN4dNpi8dNyWJklUYxTXUQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=FyG2efFq5vGjwWt+GbZoDhhNAA299Yq+wQMuKpSJ3xE3T0O7D6lfLOnJRrCX4ElZeqym9pca2pAP6QfwfQeq7vVZZr0kOXAZqX9U7+bMjFaVeHQLEbP5DOX0KE1kHD7TEja7BIWBLQlxF4aP0ZV9tT0YPVlmI6DmMCeD8u64KGs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GxvkNKhf; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GxvkNKhf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 03B3DC4CEC3; Thu, 17 Oct 2024 13:09:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1729170552; bh=qzP2YzXKrnzveGOYctsIdkN4dNpi8dNyWJklUYxTXUQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=GxvkNKhfbtfeXcI2mlIYqAxmVcE6N2cDcNqQ8Qr5j15NjN/n+CQCE4sKJf3kEUH4Q JOwTbHbwObja2/FaHFH61Vc0lXd+9Km6zWkbC+YMY+75xx1Uk1b6xru/XLvtShpJz4 VhbFFlp8EoY94V7kFp2QjboDadaQB8ZkCiA1VBUvUstDtS7Hhsyvtyif2YdohtV1ox oEfm/a5VV6d5GgvqWhXUEYVeZZ9nCwYvL0s6j0Ech/DtwJw0mjm5fMwPUBjCgDxc+m 16X+Py/vxaqrPpX3Qhc6rV3Ywtm4H+PwQb+hu0Loe2X0Mx2uJjNeq18UZS7ThiU1PE KPhDwqiIlq6Mg== From: Andreas Hindborg Date: Thu, 17 Oct 2024 15:04:40 +0200 Subject: [PATCH v3 13/13] rust: hrtimer: add maintainer entry Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241017-hrtimer-v3-v6-12-rc2-v3-13-59a75cbb44da@kernel.org> References: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> In-Reply-To: <20241017-hrtimer-v3-v6-12-rc2-v3-0-59a75cbb44da@kernel.org> To: Miguel Ojeda , Anna-Maria Behnsen , Frederic Weisbecker , Thomas Gleixner Cc: Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Lyude Paul , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.14.2 Add Andreas Hindborg as maintainer for Rust `hrtimer` abstractions. Also add Boqun Feng as reviewer. Signed-off-by: Andreas Hindborg Reviewed-by: Lyude Paul --- MAINTAINERS | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index a097afd76ded46ca7adf7a3538ad83643ad6b756..d7313743b723b385b53c0228683= d212eb49bd633 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10174,6 +10174,16 @@ F: kernel/time/timer_list.c F: kernel/time/timer_migration.* F: tools/testing/selftests/timers/ =20 +HIGH-RESOLUTION TIMERS [RUST] +M: Andreas Hindborg +R: Boqun Feng +L: rust-for-linux@vger.kernel.org +S: Supported +W: https://rust-for-linux.com +B: https://github.com/Rust-for-Linux/linux/issues +F: rust/kernel/hrtimer.rs +F: rust/kernel/hrtimer/ + HIGH-SPEED SCC DRIVER FOR AX.25 L: linux-hams@vger.kernel.org S: Orphan --=20 2.46.0