Re: [PATCH v3 2/2] rust: use Delta and a Jiffies newtype for timeouts and delays

FUJITA Tomonori <[email protected]>
Newsgroups org.kernel.vger.rust-for-linux
Message-ID <[email protected]>
On Mon, 20 Jul 2026 13:04:40 +0100
"Gary Guo" <[email protected]> wrote:

>>> I wonder if we should have time types being generic over units. So you can have
>>> `Delta<Nsec>` and `Delta<Jiffy>` and `Instant<Nsec>`, `Instant<Jiffy>`, with the
>>> generic default being set to `Nsec`.
>>> 
>>>     Delta::new(42) // Delta<Nsec>
>>>     Delta::new_jiffies(42) // Delta<Jiffy>
>>> 
>>> Thoughts?
>>
>> I think making Delta generic over the time unit makes sense; Delta
>> <Nsec> and Delta<Jiffy>.
>>
>> However, I don't think making Instant generic over the time unit is a
>> good idea, even though it clearly is for Delta.
>>
>> Instant is already generic over ClockSource, and jiffies is not a
>> clock source: it has no clockid_t, it is read via get_jiffies_64()
>> rather than ktime_get(), and it cannot be armed through hrtimer. That
>> leaves two ways to force a jiffies Instant, both looks wrong:
>>
>> a) Add a second unit parameter, Instant<C, Unit>. But then the type
>> admits meaningless combinations - there is no Instant<Monotonic,
>> Jiffy> - and jiffies still has no ClockSource to put in the C slot, so
>> (a) really collapses into (b).
> 
> We could split the `ClockSource` trait to be a generic `ClockSource` that
> supports everything and a `HrClockSource` that provides ID.

After John's point, the current ClockSource trait is exactly C's
clockid_t; ID is the clockid_t and ktime_get*() is that clockid's
accessor returning ktime_t. So it should be renamed to ClockId.

Your split; a general readable-source abstraction for Instant,
separate from ClockId, looks like a reasonable direction to revisit
when there's a user for it. Let's finish Delta<Jiffy>/Delta<Nsec>
first, since we already have in-tree users for those.


>> b) Make jiffies a fake ClockSource. But ClockSource::ID is passed
>> straight to hrtimer_setup(), so a fabricated clockid_t would make
>> HrTimer over jiffies type-check even though there is no corresponding
>> C operation.
>>
>> This matches the C world: for deltas, jiffy and nsec interconvert
>> (nsecs_to_jiffies() and friends), which is exactly what Delta<Unit>
>> with conversions models. But the jiffies counter and ktime_get()
>> values are never mixed - there isn't even an API to compare or convert
>> between them - so there is no unit-generic notion of an instant to
>> represent. A jiffies point in time, should be its own concrete type
>> rather than a specialization of Instant.
> 
> Well, `Instant` never inter-converts with anything, so a `Instant<Jiffies>`
> would be fine too. That said, we can delay making the change until we have a
> user that needs to get jiffies count. So far it seems that people just use it as
> a delta only.

Fair enough.

>>>> -/// The millisecond time unit.
>>>> -pub type Msecs = crate::ffi::c_uint;
>>>> +impl Jiffies {
>>>> +    /// A jiffies value of zero.
>>>> +    pub const ZERO: Self = Self(0);
>>>>  
>>>> -/// Converts milliseconds to jiffies.
>>>> -#[inline]
>>>> -pub fn msecs_to_jiffies(msecs: Msecs) -> Jiffies {
>>>> -    // SAFETY: The `__msecs_to_jiffies` function is always safe to call no
>>>> -    // matter what the argument is.
>>>> -    unsafe { bindings::__msecs_to_jiffies(msecs) }
>>>> +    /// Create a new [`Jiffies`] from the C side's `jiffies` value.
>>>> +    #[inline]
>>>> +    pub const fn new(jiffies: crate::ffi::c_ulong) -> Self {
>>> 
>>> Given that this is a public API not just for binding code, I think it's better
>>> to use `usize`.
>>
>> Good point, I'll use usize.
>>
>>
>>> This function can be `pub`.
>>> 
>>>> +    #[inline]
>>>> +    pub(crate) const fn as_raw(self) -> crate::ffi::c_ulong {
>>>> +        self.0
>>>> +    }
>>>> +
>>
>> I'd prefer to keep this pub(crate) until there's an in-tree user,
>> following the usual practice of not exposing public API without a
>> user. Also, if we do make it pub, it should return usize rather than
>> ffi::c_ulong, to stay consistent with the constructor change above. Do
>> you have a specific use case in mind that needs it public?
> 
> I think knowing how many jiffies are there in a `Delta<Jiffy>` is a reasonable
> need while getting a raw pointer type from other abstractions are more
> suspicious for drivers.

Makes sense. I'll make it a public as_jiffies(self) -> isize then,
instead of exposing as_raw(). Note that isize since Delta<Jiffy> is a
signed span, consistent with Delta<Nsec>.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.