* [PATCH v1 0/2] hrtimer: Add hrtimer_forward_safe_from_callback()
@ 2026-11-01 23:28 FUJITA Tomonori
2026-11-01 23:28 ` [PATCH v1 1/2] " FUJITA Tomonori
2026-11-01 23:28 ` [PATCH v1 2/2] rust: hrtimer: Use hrtimer_forward_safe_from_callback() FUJITA Tomonori
0 siblings, 2 replies; 7+ messages in thread
From: FUJITA Tomonori @ 2026-11-01 23:28 UTC (permalink / raw)
To: a.hindborg, anna-maria, frederic, gary, ojeda, tglx
Cc: acourbot, aliceryhl, bjorn3_gh, boqun, dakr, daniel.almeida,
jstultz, lossin, lyude, sboyd, tamird, tmgross, work,
linux-kernel, rust-for-linux, FUJITA Tomonori
From: FUJITA Tomonori <fujita.tomonori@gmail.com>
Safe Rust code can arm a timer while its callback is running, so the
Rust abstraction cannot offer hrtimer_forward() from the callback as a
safe API.
Thomas suggested a helper that does the check and the update with the
base lock held [1]. Patch 1 adds it. Patch 2 makes the Rust callback
context use it.
The helper is not Rust specific. As Thomas noted, it can be used for
i915_pmu too. null_blk can use it as well. I can send those
conversions after the helper is merged.
[1] https://lore.kernel.org/all/877bk3ixp5.ffs@fw13/
FUJITA Tomonori (2):
hrtimer: Add hrtimer_forward_safe_from_callback()
rust: hrtimer: Use hrtimer_forward_safe_from_callback()
include/linux/hrtimer.h | 4 ++++
kernel/time/hrtimer.c | 30 ++++++++++++++++++++++++++++++
rust/kernel/time/hrtimer.rs | 25 ++++++++++++++++++-------
3 files changed, 52 insertions(+), 7 deletions(-)
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v1 1/2] hrtimer: Add hrtimer_forward_safe_from_callback()
2026-11-01 23:28 [PATCH v1 0/2] hrtimer: Add hrtimer_forward_safe_from_callback() FUJITA Tomonori
@ 2026-11-01 23:28 ` FUJITA Tomonori
2026-11-09 21:11 ` Thomas Gleixner
2026-11-01 23:28 ` [PATCH v1 2/2] rust: hrtimer: Use hrtimer_forward_safe_from_callback() FUJITA Tomonori
1 sibling, 1 reply; 7+ messages in thread
From: FUJITA Tomonori @ 2026-11-01 23:28 UTC (permalink / raw)
To: a.hindborg, anna-maria, frederic, gary, ojeda, tglx
Cc: acourbot, aliceryhl, bjorn3_gh, boqun, dakr, daniel.almeida,
jstultz, lossin, lyude, sboyd, tamird, tmgross, work,
linux-kernel, rust-for-linux, FUJITA Tomonori
From: FUJITA Tomonori <fujita.tomonori@gmail.com>
A hrtimer can be started while its callback runs. hrtimer_forward()
writes the expiry without the base lock, so the caller has to serialize
it against a concurrent hrtimer_start(). Otherwise the write can change
the sort key of a queued timer.
Add a variant which does the check and the update with the base lock
held. If the timer is already queued, the expiry is left alone and the
expiry set by hrtimer_start() wins.
The first user is the Rust hrtimer abstraction. Safe Rust code can
start a timer while its callback runs, so forward() in the callback
can only be a safe API if the core handles a concurrent start.
Suggested-by: Thomas Gleixner <tglx@kernel.org>
Link: https://lore.kernel.org/all/877bk3ixp5.ffs@fw13/
Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
---
include/linux/hrtimer.h | 4 ++++
kernel/time/hrtimer.c | 30 ++++++++++++++++++++++++++++++
2 files changed, 34 insertions(+)
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index acfc5f93d967..f3c8542a2dbd 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -317,6 +317,10 @@ void hrtimer_update_function(struct hrtimer *timer,
extern u64
hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval);
+extern u64
+hrtimer_forward_safe_from_callback(struct hrtimer *timer, ktime_t now,
+ ktime_t interval);
+
/**
* hrtimer_forward_now() - forward the timer expiry so it expires after now
* @timer: hrtimer to forward
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index a9dc2d53aa92..9869827585af 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1121,6 +1121,36 @@ u64 hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval)
}
EXPORT_SYMBOL_GPL(hrtimer_forward);
+/**
+ * hrtimer_forward_safe_from_callback() - forward the timer expiry under the base lock
+ * @timer: hrtimer to forward
+ * @now: forward past this time
+ * @interval: the interval to forward
+ *
+ * Variant of hrtimer_forward() which is safe against a concurrent
+ * hrtimer_start(). The expiry is updated with the base lock held. If the
+ * timer is already queued, the expiry is not changed.
+ *
+ * Context: Only from the callback function of @timer.
+ *
+ * Return: The number of overruns, or 0 if the expiry was not changed.
+ */
+u64 hrtimer_forward_safe_from_callback(struct hrtimer *timer, ktime_t now,
+ ktime_t interval)
+{
+ unsigned long flags;
+ u64 orun = 0;
+
+ lock_hrtimer_base(timer, &flags);
+
+ if (!timer->is_queued)
+ orun = hrtimer_forward(timer, now, interval);
+
+ unlock_hrtimer_base(timer, &flags);
+ return orun;
+}
+EXPORT_SYMBOL_GPL(hrtimer_forward_safe_from_callback);
+
/*
* enqueue_hrtimer - internal function to (re)start a timer
*
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v1 2/2] rust: hrtimer: Use hrtimer_forward_safe_from_callback()
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-01 23:28 ` FUJITA Tomonori
2026-11-02 14:31 ` Andreas Hindborg
1 sibling, 1 reply; 7+ messages in thread
From: FUJITA Tomonori @ 2026-11-01 23:28 UTC (permalink / raw)
To: a.hindborg, anna-maria, frederic, gary, ojeda, tglx
Cc: acourbot, aliceryhl, bjorn3_gh, boqun, dakr, daniel.almeida,
jstultz, lossin, lyude, sboyd, tamird, tmgross, work,
linux-kernel, rust-for-linux, FUJITA Tomonori
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
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v1 2/2] rust: hrtimer: Use hrtimer_forward_safe_from_callback()
2026-11-01 23:28 ` [PATCH v1 2/2] rust: hrtimer: Use hrtimer_forward_safe_from_callback() FUJITA Tomonori
@ 2026-11-02 14:31 ` Andreas Hindborg
2026-11-03 2:17 ` FUJITA Tomonori
0 siblings, 1 reply; 7+ messages in thread
From: Andreas Hindborg @ 2026-11-02 14:31 UTC (permalink / raw)
To: FUJITA Tomonori, anna-maria, frederic, gary, ojeda, tglx
Cc: acourbot, aliceryhl, bjorn3_gh, boqun, dakr, daniel.almeida,
jstultz, lossin, lyude, sboyd, tamird, tmgross, work,
linux-kernel, rust-for-linux, FUJITA Tomonori
"FUJITA Tomonori" <tomo@flapping.org> writes:
> 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>
This looks good to me.
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
While reading this, I thought we should expand the safety requirement
for the handle trait, because even though handles keep the callback
target alive, they do not own the target. The armed timer does. And so a
(future) &mut method on the handle is not allowed to mutably access the
target. This implicit today, but I thought maybe we should make it
explicit.
What do you think:
diff --git a/rust/kernel/time/hrtimer.rs b/rust/kernel/time/hrtimer.rs
index ab7c568b8855..84f45a7a3a17 100644
--- a/rust/kernel/time/hrtimer.rs
+++ b/rust/kernel/time/hrtimer.rs
@@ -771,6 +771,14 @@ fn run(
/// is running. If the timer handler is running when the handle is dropped, the
/// drop method must wait for the handler to return before returning.
///
+/// While the timer is armed, the callback target is borrowed by the timer: the
+/// timer callback can create a reference to the target at any time, and for
+/// some pointer types that reference is exclusive. Implementers must not create
+/// a reference to the callback target that would conflict with the reference
+/// that [`RawHrTimerCallback::run`] creates for the pointer type in question.
+/// Deriving raw pointers from the target, as the [`Self::cancel`]
+/// implementations do, always satisfies this.
+///
/// Note: One way to satisfy the safety requirement is to call `Self::cancel` in
/// the drop implementation for `Self.`
pub unsafe trait HrTimerHandle {
diff --git a/rust/kernel/time/hrtimer/arc.rs b/rust/kernel/time/hrtimer/arc.rs
index 46ccff9e0024..eef4900cea7a 100644
--- a/rust/kernel/time/hrtimer/arc.rs
+++ b/rust/kernel/time/hrtimer/arc.rs
@@ -20,8 +20,12 @@ pub struct ArcHrTimerHandle<T>
pub(crate) inner: Arc<T>,
}
-// SAFETY: We implement drop below, and we cancel the timer in the drop
-// implementation.
+// SAFETY:
+// - We implement drop below, and we cancel the timer in the drop
+// implementation.
+// - The callback for this pointer type receives an `ArcBorrow<T>`, so the
+// timer only ever takes shared access to the callback target. References
+// derived from `self.inner` are shared as well, so they cannot conflict.
unsafe impl<T> HrTimerHandle for ArcHrTimerHandle<T>
where
T: HasHrTimer<T>,
diff --git a/rust/kernel/time/hrtimer/pin.rs b/rust/kernel/time/hrtimer/pin.rs
index 5fd374fdc480..3498c78f99f4 100644
--- a/rust/kernel/time/hrtimer/pin.rs
+++ b/rust/kernel/time/hrtimer/pin.rs
@@ -19,8 +19,13 @@ pub struct PinHrTimerHandle<'a, T>
pub(crate) inner: Pin<&'a T>,
}
-// SAFETY: We cancel the timer when the handle is dropped. The implementation of
-// the `cancel` method will block if the timer handler is running.
+// SAFETY:
+// - We cancel the timer when the handle is dropped. The implementation of the
+// `cancel` method will block if the timer handler is running.
+// - The callback for this pointer type receives a `Pin<&T>`, so the timer only
+// ever takes shared access to the callback target. The `Pin<&T>` held by the
+// handle and references derived from it are shared as well, so they cannot
+// conflict.
unsafe impl<'a, T> HrTimerHandle for PinHrTimerHandle<'a, T>
where
T: HasHrTimer<T>,
diff --git a/rust/kernel/time/hrtimer/pin_mut.rs b/rust/kernel/time/hrtimer/pin_mut.rs
index 2bba3c41d6e9..7a54889173ba 100644
--- a/rust/kernel/time/hrtimer/pin_mut.rs
+++ b/rust/kernel/time/hrtimer/pin_mut.rs
@@ -17,8 +17,12 @@ pub struct PinMutHrTimerHandle<'a, T>
_p: PhantomData<&'a mut T>,
}
-// SAFETY: We cancel the timer when the handle is dropped. The implementation of
-// the `cancel` method will block if the timer handler is running.
+// SAFETY:
+// - We cancel the timer when the handle is dropped. The implementation of the
+// `cancel` method will block if the timer handler is running.
+// - `cancel` only derives raw pointers from `self.inner`, so it does not
+// create a reference that could conflict with the `Pin<&mut T>` that the
+// callback creates.
unsafe impl<'a, T> HrTimerHandle for PinMutHrTimerHandle<'a, T>
where
T: HasHrTimer<T>,
diff --git a/rust/kernel/time/hrtimer/tbox.rs b/rust/kernel/time/hrtimer/tbox.rs
index 399ad7677043..c13a24e19550 100644
--- a/rust/kernel/time/hrtimer/tbox.rs
+++ b/rust/kernel/time/hrtimer/tbox.rs
@@ -26,8 +26,14 @@ pub struct BoxHrTimerHandle<T, A>
_p: core::marker::PhantomData<A>,
}
-// SAFETY: We implement drop below, and we cancel the timer in the drop
-// implementation.
+// SAFETY:
+// - We implement drop below, and we cancel the timer in the drop
+// implementation.
+// - `cancel` only derives raw pointers from `self.inner`, so it does not
+// create a reference that could conflict with the `Pin<&mut T>` that the
+// callback creates. The drop implementation reconstructs the `Box` only
+// after `cancel` has returned, and as it owns the `T`, no other pointer
+// exists that could arm the timer again.
unsafe impl<T, A> HrTimerHandle for BoxHrTimerHandle<T, A>
where
T: HasHrTimer<T>,
---
Best regards,
Andreas Hindborg
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v1 2/2] rust: hrtimer: Use hrtimer_forward_safe_from_callback()
2026-11-02 14:31 ` Andreas Hindborg
@ 2026-11-03 2:17 ` FUJITA Tomonori
2026-11-03 9:35 ` Andreas Hindborg
0 siblings, 1 reply; 7+ messages in thread
From: FUJITA Tomonori @ 2026-11-03 2:17 UTC (permalink / raw)
To: a.hindborg
Cc: tomo, anna-maria, frederic, gary, ojeda, tglx, acourbot,
aliceryhl, bjorn3_gh, boqun, dakr, daniel.almeida, jstultz,
lossin, lyude, sboyd, tamird, tmgross, work, linux-kernel,
rust-for-linux, fujita.tomonori
On Mon, 02 Nov 2026 15:31:35 +0100
Andreas Hindborg <a.hindborg@kernel.org> wrote:
> "FUJITA Tomonori" <tomo@flapping.org> writes:
>
>> 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>
>
> This looks good to me.
>
> Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Thanks!
> While reading this, I thought we should expand the safety requirement
> for the handle trait, because even though handles keep the callback
> target alive, they do not own the target. The armed timer does. And so a
> (future) &mut method on the handle is not allowed to mutably access the
> target. This implicit today, but I thought maybe we should make it
> explicit.
I agree that we should make this explicit. It does not depend on this
series, so could you send it as a separate patch? A few comments below.
> diff --git a/rust/kernel/time/hrtimer.rs b/rust/kernel/time/hrtimer.rs
> index ab7c568b8855..84f45a7a3a17 100644
> --- a/rust/kernel/time/hrtimer.rs
> +++ b/rust/kernel/time/hrtimer.rs
> @@ -771,6 +771,14 @@ fn run(
> /// is running. If the timer handler is running when the handle is dropped, the
> /// drop method must wait for the handler to return before returning.
> ///
> +/// While the timer is armed, the callback target is borrowed by the timer: the
> +/// timer callback can create a reference to the target at any time, and for
> +/// some pointer types that reference is exclusive.
The module doc defines the timer states as stopped, started and
running, and does not use "armed". Could we use these terms here? The
callback creates the reference only in the running state, but the
requirement needs to hold in both the started and running states,
because a started timer can move to the running state at any time.
> +/// Implementers must not create
> +/// a reference to the callback target that would conflict with the reference
> +/// that [`RawHrTimerCallback::run`] creates for the pointer type in question.
> +/// Deriving raw pointers from the target, as the [`Self::cancel`]
> +/// implementations do, always satisfies this.
Even without creating a reference, an access through a raw pointer can
be UB, for example a write to a field that the callback also uses.
`cancel` is fine because it only accesses the `HrTimer` field, which
is wrapped in `Opaque`, and hrtimer_cancel() takes the base lock. So I
think the requirement should be about accesses, not about references.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v1 2/2] rust: hrtimer: Use hrtimer_forward_safe_from_callback()
2026-11-03 2:17 ` FUJITA Tomonori
@ 2026-11-03 9:35 ` Andreas Hindborg
0 siblings, 0 replies; 7+ messages in thread
From: Andreas Hindborg @ 2026-11-03 9:35 UTC (permalink / raw)
To: FUJITA Tomonori
Cc: tomo, anna-maria, frederic, gary, ojeda, tglx, acourbot,
aliceryhl, bjorn3_gh, boqun, dakr, daniel.almeida, jstultz,
lossin, lyude, sboyd, tamird, tmgross, work, linux-kernel,
rust-for-linux, fujita.tomonori
FUJITA Tomonori <tomo@flapping.org> writes:
> On Mon, 02 Nov 2026 15:31:35 +0100
> Andreas Hindborg <a.hindborg@kernel.org> wrote:
>
>> "FUJITA Tomonori" <tomo@flapping.org> writes:
>>
>>> 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>
>>
>> This looks good to me.
>>
>> Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
>
> Thanks!
>
>> While reading this, I thought we should expand the safety requirement
>> for the handle trait, because even though handles keep the callback
>> target alive, they do not own the target. The armed timer does. And so a
>> (future) &mut method on the handle is not allowed to mutably access the
>> target. This implicit today, but I thought maybe we should make it
>> explicit.
>
> I agree that we should make this explicit. It does not depend on this
> series, so could you send it as a separate patch? A few comments below.
Yes, I did not intend to hijack this series. Just wanted your input.
>
>> diff --git a/rust/kernel/time/hrtimer.rs b/rust/kernel/time/hrtimer.rs
>> index ab7c568b8855..84f45a7a3a17 100644
>> --- a/rust/kernel/time/hrtimer.rs
>> +++ b/rust/kernel/time/hrtimer.rs
>> @@ -771,6 +771,14 @@ fn run(
>> /// is running. If the timer handler is running when the handle is dropped, the
>> /// drop method must wait for the handler to return before returning.
>> ///
>> +/// While the timer is armed, the callback target is borrowed by the timer: the
>> +/// timer callback can create a reference to the target at any time, and for
>> +/// some pointer types that reference is exclusive.
>
> The module doc defines the timer states as stopped, started and
> running, and does not use "armed". Could we use these terms here?
Yes, good point.
> The
> callback creates the reference only in the running state, but the
> requirement needs to hold in both the started and running states,
> because a started timer can move to the running state at any time.
>
>> +/// Implementers must not create
>> +/// a reference to the callback target that would conflict with the reference
>> +/// that [`RawHrTimerCallback::run`] creates for the pointer type in question.
>> +/// Deriving raw pointers from the target, as the [`Self::cancel`]
>> +/// implementations do, always satisfies this.
>
> Even without creating a reference, an access through a raw pointer can
> be UB, for example a write to a field that the callback also uses.
Right, but creating the pointer and using it for offset calculations is
fine. I can try to make that more clear.
> `cancel` is fine because it only accesses the `HrTimer` field, which
> is wrapped in `Opaque`, and hrtimer_cancel() takes the base lock. So I
> think the requirement should be about accesses, not about references.
I see. I'll try to rephrase a bit.
Best regards,
Andreas Hindborg
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v1 1/2] hrtimer: Add hrtimer_forward_safe_from_callback()
2026-11-01 23:28 ` [PATCH v1 1/2] " FUJITA Tomonori
@ 2026-11-09 21:11 ` Thomas Gleixner
0 siblings, 0 replies; 7+ messages in thread
From: Thomas Gleixner @ 2026-11-09 21:11 UTC (permalink / raw)
To: FUJITA Tomonori, a.hindborg, anna-maria, frederic, gary, ojeda
Cc: acourbot, aliceryhl, bjorn3_gh, boqun, dakr, daniel.almeida,
jstultz, lossin, lyude, sboyd, tamird, tmgross, work,
linux-kernel, rust-for-linux, FUJITA Tomonori
On Mon, Nov 02 2026 at 08:28, FUJITA Tomonori wrote:
> From: FUJITA Tomonori <fujita.tomonori@gmail.com>
>
> A hrtimer can be started while its callback runs. hrtimer_forward()
> writes the expiry without the base lock, so the caller has to serialize
> it against a concurrent hrtimer_start(). Otherwise the write can change
> the sort key of a queued timer.
>
> Add a variant which does the check and the update with the base lock
> held. If the timer is already queued, the expiry is left alone and the
> expiry set by hrtimer_start() wins.
>
> The first user is the Rust hrtimer abstraction. Safe Rust code can
> start a timer while its callback runs, so forward() in the callback
> can only be a safe API if the core handles a concurrent start.
>
> Suggested-by: Thomas Gleixner <tglx@kernel.org>
> Link: https://lore.kernel.org/all/877bk3ixp5.ffs@fw13/
> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
I don't have anything conflicting at the moment, so this can go through
the rust tree.
Reviewed-by: Thomas Gleixner <tglx@kernel.org>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-11-09 21:11 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH v1 2/2] rust: hrtimer: Use hrtimer_forward_safe_from_callback() FUJITA Tomonori
2026-11-02 14:31 ` Andreas Hindborg
2026-11-03 2:17 ` FUJITA Tomonori
2026-11-03 9:35 ` Andreas Hindborg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®