[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <DANP9ATT1T5W.1KP4992E26FTP@nvidia.com>
Date: Mon, 16 Jun 2025 14:14:29 +0900
From: "Alexandre Courbot" <acourbot@...dia.com>
To: "Boqun Feng" <boqun.feng@...il.com>
Cc: "Miguel Ojeda" <ojeda@...nel.org>, "Alex Gaynor"
<alex.gaynor@...il.com>, "Gary Guo" <gary@...yguo.net>,
Björn Roy Baron <bjorn3_gh@...tonmail.com>, "Andreas
Hindborg" <a.hindborg@...nel.org>, "Alice Ryhl" <aliceryhl@...gle.com>,
"Trevor Gross" <tmgross@...ch.edu>, "Danilo Krummrich" <dakr@...nel.org>,
"David Airlie" <airlied@...il.com>, "Simona Vetter" <simona@...ll.ch>,
"Maarten Lankhorst" <maarten.lankhorst@...ux.intel.com>, "Maxime Ripard"
<mripard@...nel.org>, "Thomas Zimmermann" <tzimmermann@...e.de>, "Benno
Lossin" <lossin@...nel.org>, "John Hubbard" <jhubbard@...dia.com>, "Ben
Skeggs" <bskeggs@...dia.com>, "Joel Fernandes" <joelagnelf@...dia.com>,
"Timur Tabi" <ttabi@...dia.com>, "Alistair Popple" <apopple@...dia.com>,
<linux-kernel@...r.kernel.org>, <rust-for-linux@...r.kernel.org>,
<nouveau@...ts.freedesktop.org>, <dri-devel@...ts.freedesktop.org>
Subject: Re: [PATCH v5 04/23] rust: add new `num` module with `PowerOfTwo`
type
On Sun Jun 15, 2025 at 2:08 AM JST, Boqun Feng wrote:
> On Fri, Jun 13, 2025 at 11:16:10PM +0900, Alexandre Courbot wrote:
> [...]
>> >> + /// Aligns `self` down to `alignment`.
>> >> + ///
>> >> + /// # Examples
>> >> + ///
>> >> + /// ```
>> >> + /// use kernel::num::PowerOfTwo;
>> >> + ///
>> >> + /// assert_eq!(PowerOfTwo::<u32>::new(0x1000).align_down(0x4fff), 0x4000);
>> >> + /// ```
>> >> + #[inline(always)]
>> >> + pub const fn align_down(self, value: $t) -> $t {
>> >
>> > I'm late to party, but could we instead implement:
>> >
>> > pub const fn round_down<i32>(value: i32, shift: i32) -> i32 {
>> > value & !((1 << shift) - 1)
>> > }
>> >
>> > pub const fn round_up<i32>(value: i32, shift: i32) -> i32 {
>> > let mask = (1 << shift) - 1;
>> > value.wrapping_add(mask) & !mask
>> > }
>> >
>> > ? It's much harder to pass an invalid alignment with this.
>>
>> It also forces you to think in terms of shifts instead of values - i.e.
>> you cannot round to `0x1000` as it commonly done in the kernel, now you
>
> Well, for const values, you can always define:
>
> const ROUND_SHIFT_0X1000: i32 = 12;
>
> because `0x1000` is just a name ;-)
>
> or we define an Alignment in term of the shift:
>
> pub struct Alignment {
> shift: i8,
> }
>
> ipml Alignment {
> pub const new(shift: i8) -> Self {
> Self { shift }
> }
> }
>
> then
>
> const ALIGN_0x1000: Alignment = Alignment::new(12);
Now you take the risk that due to a typo the name of the constant does
not match the alignment - something you cannot have if you use values
directly (and if one wants to reason in terms of alignment, they can do
`PowerOfTwo::<u32>::new(1 << 12)`, or we can even add an alternative
constructor for that).
>
> and
>
> pub const fn round_down_i32(value: i32, align: Alignment) -> i32 {
> ...
> }
>
> My point was that instead of the value itself, we can always use the
> shift to represent a power of two, and that would avoid troubles when we
> need to check the internal representation.
Storing the shift instead of the value means that we need to recreate
the latter every time we need to access it (e.g. to apply a mask).
>
> That said, after some experiments by myself, I haven't found any
> significant difference between shift representations vs value
> representations. So no strong reason of using a shift representation.
I'm open to any representation but AFAICT there is no obvious benefit
(and a slight drawback when requesting the value) in representing these
as a shift.
Powered by blists - more mailing lists