From: Alice Ryhl <aliceryhl@google.com>
To: Yury Norov <ynorov@nvidia.com>
Cc: "Alexandre Courbot" <acourbot@nvidia.com>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Trevor Gross" <tmgross@umich.edu>,
"Danilo Krummrich" <dakr@kernel.org>,
"Yury Norov" <yury.norov@gmail.com>,
"John Hubbard" <jhubbard@nvidia.com>,
"Alistair Popple" <apopple@nvidia.com>,
"Joel Fernandes" <joelagnelf@nvidia.com>,
"Timur Tabi" <ttabi@nvidia.com>, "Edwin Peer" <epeer@nvidia.com>,
"Eliot Courtney" <ecourtney@nvidia.com>,
"Daniel Almeida" <daniel.almeida@collabora.com>,
"Dirk Behme" <dirk.behme@de.bosch.com>,
"Steven Price" <steven.price@arm.com>,
rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/6] rust: num: add `shr` and `shl` methods to `Bounded`
Date: Wed, 21 Jan 2026 10:10:28 +0000 [thread overview]
Message-ID: <aXCmFNMGkfBYEIjG@google.com> (raw)
In-Reply-To: <aXCLNRVGGqsYeiBM@yury>
On Wed, Jan 21, 2026 at 03:15:49AM -0500, Yury Norov wrote:
> On Tue, Jan 20, 2026 at 03:17:54PM +0900, Alexandre Courbot wrote:
> > Shifting a `Bounded` left or right changes the number of bits required
> > to represent the value. Add methods that perform the shift and return a
> > `Bounded` with the appropriately adjusted bit width.
> >
> > These methods are particularly useful for bitfield extraction.
> >
> > Suggested-by: Alice Ryhl <aliceryhl@google.com>
> > Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
> > ---
> > rust/kernel/num/bounded.rs | 40 ++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 40 insertions(+)
> >
> > diff --git a/rust/kernel/num/bounded.rs b/rust/kernel/num/bounded.rs
> > index 5ef8361cf5d5..6e3f4a7a5262 100644
> > --- a/rust/kernel/num/bounded.rs
> > +++ b/rust/kernel/num/bounded.rs
> > @@ -475,6 +475,46 @@ pub fn cast<U>(self) -> Bounded<U, N>
> > // `N` bits, and with the same signedness.
> > unsafe { Bounded::__new(value) }
> > }
> > +
> > + /// Right-shifts `self` by `SHIFT` and returns the result as a `Bounded<_, { N - SHIFT }>`.
> > + ///
> > + /// # Examples
> > + ///
> > + /// ```
> > + /// use kernel::num::Bounded;
> > + ///
> > + /// let v = Bounded::<u32, 16>::new::<0xff00>();
> > + /// let v_shifted: Bounded::<u32, 8> = v.shr::<8, _>();
>
> This syntax is really confusing. Does it work for runtime shifts?
> Is there any chance to make it just v.shr(8)?
The ::<NUM> syntax is how you pass a build-time constant value in Rust.
The syntax 'v.shr(8)' implies that 8 is a runtime value, and not a
build-time constant. I agree it's ugly, but that's how it is.
For runtime shifts, we can make it 'v.shr(8)' or even 'v >> 8' using
operator overloading, but see my further reply below:
> > + }
> > +
> > + /// Left-shifts `self` by `SHIFT` and returns the result as a `Bounded<_, { N + SHIFT }>`.
> > + ///
> > + /// # Examples
> > + ///
> > + /// ```
> > + /// use kernel::num::Bounded;
> > + ///
> > + /// let v = Bounded::<u32, 8>::new::<0xff>();
> > + /// let v_shifted: Bounded::<u32, 16> = v.shl::<8, _>();
> > + ///
> > + /// assert_eq!(v_shifted.get(), 0xff00);
> > + /// ```
> > + pub fn shl<const SHIFT: u32, const RES: u32>(self) -> Bounded<T, RES> {
> > + const { assert!(RES == N + SHIFT) }
> > +
> > + // SAFETY: we shift the value left by `SHIFT`, augmenting the number of bits needed to
> > + // represent the shifted value by as much, and just asserted that `RES == N + SHIFT`.
> > + unsafe { Bounded::__new(self.0 << SHIFT) }
> > + }
>
> So, it protects most significant bits when shifting left, but doesn't
> protect least significant bits when shifting right.
>
> It also makes impossible to left-shift Bounded::<u32, 32> at all, or
> shift Bounded::<u32, 31> for 2 or more bits. This doesn't look nice.
>
> At this layer, there's seemingly nothing wrong to loose bits during
> regular shift, just like non-bounded integers do. (Lets consider them
> naturally bounded.) At higher layers, people may add any extra checks
> as desired.
>
> Even more, you mention you're going to use .shl and .shr for bitfield
> extraction, which means you want to loose some bits intentionally.
>
> Let's design shifts like this. Plain .shl() and .shr() will operate on
> bounded integers just like '<<' and '>>' operate on non-bounded ones,
> i.e. they may loose bits and the result has the same bit capacity. (But
> shifting over the capacity should be be forbidden as undef).
>
> If I want to adjust the capacity, I just do it explicitly:
>
> let x = Bounded::<u32, 12>::new::<0x123>();
> let a = x.shl(4); // 12-bit 0x230
> let b = x.extend::<12+4>().shl(4) // 16-bit 0x1230
> let c = x.shr(4); // 12-bit 0x012
> let d = if x & 0xf { None } else { x.shr(4).try_shrink::<12-4>() }
>
> For b and d you can invent handy helpers, of course, and for a and c
> you can add 'safe' versions that will check shifted-out parts for
> emptiness at runtime, in case you need it.
This 'shr' method came up from a discussion that Alexandre and I had at
plumbers. The entire point of them is that when you shift right by a
compile-time constant amount, you can change the bit capacity in the
type, and doing exactly that lets us remove BUILD_BUG_ON calls that Nova
has right now. (Right now Nova does a shift-right by a compile-time
constant, then uses BUILD_BUG_ON to assert that the resulting *runtime
value* has the desired target bit-capacity.)
So if we want a shift right method that doesn't change the bit-capacity,
we can do that. It can even use the ordinary '>>' operator. But the
purpose of this patch is precisely to support shifts that:
1. Shift by a compile-time constant amount.
2. Change the bit-capacity accordingly.
All that to say ... support for left-shifting Bounded::<u32, 32> and
similar certainly makes sense as something we could support, but that's
not what this patch is trying to achieve. Ultimately, the end-goal of
this patch is to allow us to get rid of BUILD_BUG_ON() calls operating
on runtime values, while still performing the same check that the
bit-capacity is as expected at build-time - just using types instead of
compiler optimizations to check it.
Alice
next prev parent reply other threads:[~2026-01-21 10:10 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-20 6:17 [PATCH 0/6] rust: add `bitfield!` and `register!` macros Alexandre Courbot
2026-01-20 6:17 ` [PATCH 1/6] rust: num: add `shr` and `shl` methods to `Bounded` Alexandre Courbot
2026-01-20 8:44 ` Alice Ryhl
2026-01-20 12:53 ` Alexandre Courbot
2026-01-20 16:12 ` kernel test robot
2026-01-21 8:15 ` Yury Norov
2026-01-21 10:10 ` Alice Ryhl [this message]
2026-01-20 6:17 ` [PATCH 2/6] rust: num: add `as_bool` method to `Bounded<_, 1>` Alexandre Courbot
2026-01-20 8:45 ` Alice Ryhl
2026-01-20 6:17 ` [PATCH 3/6] rust: add `bitfield!` macro Alexandre Courbot
2026-01-20 11:45 ` Dirk Behme
2026-01-20 12:37 ` Miguel Ojeda
2026-01-20 12:47 ` Dirk Behme
2026-01-20 13:08 ` Miguel Ojeda
2026-01-20 13:20 ` Alexandre Courbot
2026-01-20 21:02 ` Miguel Ojeda
2026-01-20 12:51 ` Alexandre Courbot
2026-01-21 9:16 ` Yury Norov
2026-01-26 13:35 ` Alexandre Courbot
2026-01-27 2:55 ` Yury Norov
2026-01-27 3:25 ` Joel Fernandes
2026-01-27 4:49 ` Yury Norov
2026-01-27 10:41 ` Alexandre Courbot
2026-01-27 10:55 ` Miguel Ojeda
2026-01-28 5:27 ` Yury Norov
2026-01-28 14:12 ` Alexandre Courbot
2026-01-28 18:05 ` Yury Norov
2026-01-29 13:40 ` Alexandre Courbot
2026-01-29 15:12 ` Miguel Ojeda
2026-01-27 11:00 ` Joel Fernandes
2026-01-27 15:02 ` Gary Guo
2026-01-28 1:23 ` Alexandre Courbot
2026-01-28 4:33 ` Yury Norov
2026-01-28 14:02 ` Alexandre Courbot
2026-01-28 18:12 ` Yury Norov
2026-01-27 9:57 ` Alexandre Courbot
2026-01-27 21:03 ` John Hubbard
2026-01-27 21:10 ` Gary Guo
2026-01-27 21:22 ` John Hubbard
2026-01-28 1:28 ` Alexandre Courbot
2026-01-28 1:41 ` John Hubbard
2026-01-20 6:17 ` [PATCH 4/6] rust: bitfield: Add KUNIT tests for bitfield Alexandre Courbot
2026-01-20 6:17 ` [PATCH 5/6] rust: io: add `register!` macro Alexandre Courbot
2026-01-20 6:17 ` [PATCH FOR REFERENCE 6/6] gpu: nova-core: use the kernel `register!` and `bitfield!` macros Alexandre Courbot
2026-01-20 13:14 ` [PATCH 0/6] rust: add `bitfield!` and `register!` macros Miguel Ojeda
2026-01-20 13:38 ` Danilo Krummrich
2026-01-20 13:50 ` Miguel Ojeda
2026-01-20 14:18 ` Danilo Krummrich
2026-01-20 14:57 ` Miguel Ojeda
2026-01-20 15:27 ` Danilo Krummrich
2026-01-20 15:48 ` Miguel Ojeda
2026-01-20 20:01 ` Danilo Krummrich
2026-01-20 20:31 ` Miguel Ojeda
2026-01-21 5:57 ` Yury Norov
2026-01-21 6:55 ` Alexandre Courbot
2026-01-26 14:03 ` Joel Fernandes
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=aXCmFNMGkfBYEIjG@google.com \
--to=aliceryhl@google.com \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=apopple@nvidia.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=dirk.behme@de.bosch.com \
--cc=ecourtney@nvidia.com \
--cc=epeer@nvidia.com \
--cc=gary@garyguo.net \
--cc=jhubbard@nvidia.com \
--cc=joelagnelf@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=steven.price@arm.com \
--cc=tmgross@umich.edu \
--cc=ttabi@nvidia.com \
--cc=ynorov@nvidia.com \
--cc=yury.norov@gmail.com \
/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.