From: FUJITA Tomonori <tomo@flapping.org>
To: a.hindborg@kernel.org, anna-maria@linutronix.de,
frederic@kernel.org, gary@garyguo.net, ojeda@kernel.org,
tglx@kernel.org
Cc: acourbot@nvidia.com, aliceryhl@google.com,
bjorn3_gh@protonmail.com, boqun@kernel.org, dakr@kernel.org,
daniel.almeida@collabora.com, jstultz@google.com,
lossin@kernel.org, lyude@redhat.com, sboyd@kernel.org,
tamird@kernel.org, tmgross@umich.edu, work@onurozkan.dev,
linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org,
FUJITA Tomonori <fujita.tomonori@gmail.com>
Subject: [PATCH v1 2/2] rust: hrtimer: Use hrtimer_forward_safe_from_callback()
Date: Mon, 2 Nov 2026 08:28:29 +0900 [thread overview]
Message-ID: <20261101232829.593680-3-tomo@flapping.org> (raw)
In-Reply-To: <20261101232829.593680-1-tomo@flapping.org>
From: FUJITA Tomonori <fujita.tomonori@gmail.com>
Safe Rust code can start a timer while its callback runs. A timer
started through Arc<T> or Pin<&T> can be started again from another
clone or copy of the pointer. HrTimerCallbackContext::forward() calls
hrtimer_forward(), which writes the expiry without the base lock, so
the write can race with the concurrent hrtimer_start().
Call hrtimer_forward_safe_from_callback() instead. It does the update
with the base lock held. If the timer is already queued by a concurrent
start, the expiry is left alone and 0 is returned.
HrTimer::forward() keeps calling hrtimer_forward(). It takes
Pin<&mut Self>, so no other reference to the timer exists and no
concurrent start is possible. Narrow the safety requirement of
raw_forward() to exclusive access, since the callback context no longer
uses it.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
---
rust/kernel/time/hrtimer.rs | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/rust/kernel/time/hrtimer.rs b/rust/kernel/time/hrtimer.rs
index a53f7f1341be..bf4094d84822 100644
--- a/rust/kernel/time/hrtimer.rs
+++ b/rust/kernel/time/hrtimer.rs
@@ -521,8 +521,7 @@ pub(crate) unsafe fn raw_cancel(this: *const Self) -> bool {
/// # Safety
///
/// - `self_ptr` must point to a valid `Self`.
- /// - The caller must either have exclusive access to the data pointed at by `self_ptr`, or be
- /// within the context of the timer callback.
+ /// - The caller must have exclusive access to the data pointed at by `self_ptr`.
#[inline]
unsafe fn raw_forward(self_ptr: *mut Self, now: HrTimerInstant<T>, interval: Delta) -> u64
where
@@ -1060,13 +1059,25 @@ pub(crate) unsafe fn from_raw(timer: *mut HrTimer<T>) -> Self {
/// Conditionally forward the timer.
///
- /// This function is identical to [`HrTimer::forward()`] except that it may only be used from
- /// within the context of a [`HrTimer`] callback.
+ /// This function does the same as [`HrTimer::forward()`], but it may only be used from within
+ /// the context of a [`HrTimer`] callback, and it is safe against a concurrent start operation.
+ /// If the timer was started by a concurrent start operation, the expiry is not changed, this
+ /// function returns 0, and the expiry set by the start operation is used.
pub fn forward(&mut self, now: HrTimerInstant<T>, interval: Delta) -> u64 {
+ // SAFETY: By our type invariants, `self.0` always points to a valid `HrTimer<T>`.
+ let c_timer_ptr = unsafe { HrTimer::<T>::raw_get(self.0.as_ptr()) };
+
// SAFETY:
- // - We are guaranteed to be within the context of a timer callback by our type invariants
- // - By our type invariants, `self.0` always points to a valid `HrTimer<T>`
- unsafe { HrTimer::<T>::raw_forward(self.0.as_ptr(), now, interval) }
+ // - `c_timer_ptr` is initialized and valid.
+ // - By our type invariants, we are within the context of the timer callback, as
+ // `hrtimer_forward_safe_from_callback()` requires.
+ unsafe {
+ bindings::hrtimer_forward_safe_from_callback(
+ c_timer_ptr,
+ now.as_nanos(),
+ interval.as_nanos(),
+ )
+ }
}
/// Conditionally forward the timer.
--
2.43.0
next prev parent reply other threads:[~2026-11-01 23:33 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-01 23:28 [PATCH v1 0/2] hrtimer: Add hrtimer_forward_safe_from_callback() FUJITA Tomonori
2026-11-01 23:28 ` [PATCH v1 1/2] " FUJITA Tomonori
2026-11-09 21:11 ` Thomas Gleixner
2026-11-01 23:28 ` FUJITA Tomonori [this message]
2026-11-02 14:31 ` [PATCH v1 2/2] rust: hrtimer: Use hrtimer_forward_safe_from_callback() Andreas Hindborg
2026-11-03 2:17 ` FUJITA Tomonori
2026-11-03 9:35 ` Andreas Hindborg
2026-11-12 12:47 ` [PATCH v1 0/2] hrtimer: Add hrtimer_forward_safe_from_callback() Andreas Hindborg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261101232829.593680-3-tomo@flapping.org \
--to=tomo@flapping.org \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=aliceryhl@google.com \
--cc=anna-maria@linutronix.de \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=frederic@kernel.org \
--cc=fujita.tomonori@gmail.com \
--cc=gary@garyguo.net \
--cc=jstultz@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=lyude@redhat.com \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=sboyd@kernel.org \
--cc=tamird@kernel.org \
--cc=tglx@kernel.org \
--cc=tmgross@umich.edu \
--cc=work@onurozkan.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.