From: "Gary Guo" <gary@garyguo.net>
To: "Alexandre Courbot" <acourbot@nvidia.com>, "Gary Guo" <gary@garyguo.net>
Cc: "Danilo Krummrich" <dakr@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Daniel Almeida" <daniel.almeida@collabora.com>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Boqun Feng" <boqun@kernel.org>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Trevor Gross" <tmgross@umich.edu>,
"Tamir Duberstein" <tamird@kernel.org>,
"Onur Özkan" <work@onurozkan.dev>,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Bjorn Helgaas" <bhelgaas@google.com>,
"Krzysztof Wilczyński" <kwilczynski@kernel.org>,
driver-core@lists.linux.dev, rust-for-linux@vger.kernel.org,
linux-kernel@vger.kernel.org, nova-gpu@lists.linux.dev,
dri-devel@lists.freedesktop.org, linux-pci@vger.kernel.org
Subject: Re: [PATCH v3 03/16] rust: mem: add `AsRepr` and `AsReprMut`
Date: Wed, 26 Aug 2026 12:50:48 +0100 [thread overview]
Message-ID: <DKYUQ9CWIXKJ.3FSWLPWHXIBK@garyguo.net> (raw)
In-Reply-To: <DKYU6RA4PD45.J2EMZIOB0BBF@nvidia.com>
On Wed Aug 26, 2026 at 12:25 PM BST, Alexandre Courbot wrote:
> On Wed Aug 19, 2026 at 8:09 PM JST, Gary Guo wrote:
>> Some API like atomics and I/O operate on primitives only; therefore other
>> types would need to converted to these primitive first. Add two traits
>> `AsRepr` and `AsReprMut` to indicate that the type can be turned into a
>> primitive for these operations.
>>
>> Conceptually, `T: AsRepr` means that `&T` can be viewed as `&T::Repr` and
>> thus it has only a round-trip transmutability requirement. `T: AsReprMut`
>> means that `&mut T` can be viewed as `&mut T::Repr` and thus it needs to
>> support bi-directional transmutability.
>>
>> To avoid duplicating implementation, all repr types are normalized to
>> unsigned integers.
>>
>> Signed-off-by: Gary Guo <gary@garyguo.net>
>> ---
>> rust/kernel/mem.rs | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 148 insertions(+)
>>
>> diff --git a/rust/kernel/mem.rs b/rust/kernel/mem.rs
>> index a0901cbe1b2d..5bce381d8895 100644
>> --- a/rust/kernel/mem.rs
>> +++ b/rust/kernel/mem.rs
>> @@ -35,3 +35,151 @@ pub const fn transmute<Src: IntoBytes, Dst: FromBytes>(val: Src) -> Dst {
>> // SAFETY: transmute is safe with `IntoBytes` and `FromBytes` bounds.
>> unsafe { transmute_unchecked(val) }
>> }
>> +
>> +/// Type that is layout-compatible with a primitive representation.
>> +///
>> +/// # Round-trip transmutability
>> +///
>> +/// `T` is round-trip transmutable to `U` if and only if both of these properties hold:
>> +///
>> +/// - Any valid bit pattern for `T` is also a valid bit pattern for `U`.
>> +/// - Transmuting a value of type `T` to `U` and then to `T` again
>> +/// yields a value that is in all aspects equivalent to the original value.
>> +///
>> +/// # Safety
>> +///
>> +/// - [`Self`] must have the same size and alignment as [`Self::Repr`].
>> +/// - [`Self`] must be [round-trip transmutable] to [`Self::Repr`].
>> +///
>> +/// [round-trip transmutable]: AsRepr#round-trip-transmutability
>> +pub unsafe trait AsRepr: Sized {
>
> I'm a bit confused by the naming of this trait - the commit message
> mentions that it means that "`&T` can be viewed as `&T::Repr`", but such
> a method doesn't exist. Instead we have an `AsRepr` trait with an
> `into_repr` method that makes a copy.
>
> Can we either rename this to `IntoRepr` (and `AsReprMut` into `FromRepr`
> I guess?), or maybe better, have `fn as_repr(this: &Self) ->
> &Self::Repr` (on top of which `into_repr` could be implemented if
> useful) so the names of the trait and provided method align, while also
> making the commit message match the actual API? I haven't tried but
> since all the representations we are working with are primitives that
> implement `Copy`, I intuitively think it should work just as well.
>
> Same would apply to `AsReprMut`.
>
> Since this is becoming core infrastructure, I guess `as_repr` will also
> become valuable when we want to do in-place access (with e.g. atomics)
> or use it with larger types that we don't want to copy.
Good point. I'll add a `Repr: Copy` bound and switch impl of `as_repr`.
`AsRepr` is meant as "have a primitive representation", which I imagine to be
most likely just integers. I didn't say "integers" specifically because we
cannot lose provenance on pointers so pointers are not integer represented.
So I do think we might also want to make `Copy` a supertrait of `AsRepr`?
`AtomicType` current requires it.
>
>> + /// Primitive representation of this type.
>> + type Repr;
>> +
>> + /// Convert from [`AsRepr::Repr`] to `Self`.
>> + ///
>> + /// # Safety
>> + ///
>> + /// `repr` must be a valid bit patern of `Self`. If `repr` is previously obtained using
>
> nit: s/patern/pattern.
>
>> + /// [`AsRepr::into_repr`], then it will always be safe.
>> + #[inline(always)]
>> + unsafe fn from_repr_unchecked(repr: Self::Repr) -> Self {
>> + // SAFETY: Per safety requirement of the trait.
>
> "... of the trait and method" maybe?
>
>> + unsafe { transmute_unchecked(repr) }
>> + }
>> +
>> + /// Convert from `Self` to [`AsRepr::Repr`].
>> + #[inline(always)]
>> + fn into_repr(this: Self) -> Self::Repr {
>> + // SAFETY: Per safety requirement of the trait.
>> + unsafe { transmute_unchecked(this) }
>> + }
>> +}
>> +
>> +/// Type that is bi-directionally transmutable with a primitive representation.
>> +///
>> +/// # Safety
>> +///
>> +/// - [`Self`] must be [transmutable] from [`Self::Repr`].
>
> nit: missing backticks on [transmutable].
Ah, this is a term. I should remove backtick from the link instead.
>
> <...>
>> +#[cfg(target_pointer_width = "32")]
>> +const _: () = {
>> + // SAFETY: usize has the same size and alignment with u32, and is round-trip transmutable to it.
>> + unsafe impl AsRepr for usize {
>> + type Repr = u32;
>> + }
>> +
>> + // SAFETY: isize has the same size and alignment with u32, and is round-trip transmutable to it.
>> + unsafe impl AsRepr for isize {
>> + type Repr = u32;
>> + }
>> +
>> + // SAFETY: usize is transmutable from u32.
>> + unsafe impl AsReprMut for usize {}
>> + // SAFETY: isize is transmutable from u32.
>> + unsafe impl AsReprMut for isize {}
>> +};
>> +
>> +#[cfg(target_pointer_width = "64")]
>> +const _: () = {
>> + // SAFETY: usize has the same size and alignment with u64, and is round-trip transmutable to it.
>> + unsafe impl AsRepr for usize {
>> + type Repr = u64;
>> + }
>> +
>> + // SAFETY: isize has the same size and alignment with u64, and is round-trip transmutable to it.
>> + unsafe impl AsRepr for isize {
>> + type Repr = u64;
>> + }
>> +
>> + // SAFETY: usize is transmutable from u64.
>> + unsafe impl AsReprMut for usize {}
>> + // SAFETY: isize is transmutable from u64.
>> + unsafe impl AsReprMut for isize {}
>> +};
>
> By making these available, aren't we running into the same
> non-portability issue [1] that we discussed on the `casts` module?
>
> [1] https://lore.kernel.org/all/DK9A6KGK5JQD.3U23MBEMSAXBK@garyguo.net/
I added it because `Atomic` would require it. However, it does make it possible
to create non-portable if `usize` is used on a `I/O` type that does not
implement `IoCapable<u64>` on 64-bit platforms.
I guess an option is to have `usize` stay as `usize` and we add a forwarding
`usize` impl in atomic module instead.
Best,
Gary
next prev parent reply other threads:[~2026-08-26 11:50 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-19 11:09 [PATCH v3 00/16] rust: io: support register projections and remove relative registers Gary Guo
2026-08-19 11:09 ` [PATCH v3 01/16] rust: io: register: reimplement as proc macro Gary Guo
2026-08-27 6:16 ` Alexandre Courbot
2026-08-27 14:23 ` Gary Guo
2026-08-19 11:09 ` [PATCH v3 02/16] rust: mem: add `transmute` with deferred size check Gary Guo
2026-08-27 6:24 ` Alexandre Courbot
2026-08-27 14:26 ` Gary Guo
2026-08-19 11:09 ` [PATCH v3 03/16] rust: mem: add `AsRepr` and `AsReprMut` Gary Guo
2026-08-26 11:25 ` Alexandre Courbot
2026-08-26 11:50 ` Gary Guo [this message]
2026-08-26 13:30 ` Alexandre Courbot
2026-08-19 11:09 ` [PATCH v3 04/16] rust: io: perform conversions using `AsRepr` Gary Guo
2026-08-27 6:53 ` Alexandre Courbot
2026-08-27 14:21 ` Gary Guo
2026-08-27 14:39 ` Alexandre Courbot
2026-08-19 11:09 ` [PATCH v3 05/16] rust: io: support register projections Gary Guo
2026-08-27 7:01 ` Alexandre Courbot
2026-08-19 11:09 ` [PATCH v3 06/16] rust: io: register: allow explicit base type specification Gary Guo
2026-08-27 7:17 ` Alexandre Courbot
2026-08-19 11:09 ` [PATCH v3 07/16] gpu: nova-core: specify base type for registers Gary Guo
2026-08-27 11:20 ` Alexandre Courbot
2026-08-19 11:09 ` [PATCH v3 08/16] drm/tyr: " Gary Guo
2026-08-19 11:09 ` [PATCH v3 09/16] samples: rust: pci: " Gary Guo
2026-08-27 11:29 ` Alexandre Courbot
2026-08-19 11:09 ` [PATCH v3 10/16] rust: io: register: make register have a typed base Gary Guo
2026-08-27 13:42 ` Alexandre Courbot
2026-08-27 14:32 ` Gary Guo
2026-08-28 0:01 ` Alexandre Courbot
2026-08-19 11:09 ` [PATCH v3 11/16] rust: io: register: support fixed offset register without bitfield Gary Guo
2026-08-28 0:38 ` Alexandre Courbot
2026-08-19 11:09 ` [PATCH v3 12/16] gpu: nova-core: use projection for PFALCON and PFALCON2 registers Gary Guo
2026-08-28 1:04 ` Alexandre Courbot
2026-08-28 1:24 ` Alexandre Courbot
2026-08-19 11:09 ` [PATCH v3 13/16] gpu: nova-core: convert hshub0 from relative register to projection Gary Guo
2026-08-28 1:29 ` Alexandre Courbot
2026-08-19 11:09 ` [PATCH v3 14/16] rust: io: register: remove relative registers Gary Guo
2026-08-28 1:33 ` Alexandre Courbot
2026-08-19 11:09 ` [PATCH v3 15/16] rust: io: register: remove `Register` trait and cleanup macro Gary Guo
2026-08-28 2:07 ` Alexandre Courbot
2026-08-19 11:09 ` [PATCH v3 16/16] rust: io: register: unify handling of register with/without bitfields Gary Guo
2026-08-28 2:07 ` Alexandre Courbot
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=DKYUQ9CWIXKJ.3FSWLPWHXIBK@garyguo.net \
--to=gary@garyguo.net \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=airlied@gmail.com \
--cc=aliceryhl@google.com \
--cc=bhelgaas@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=driver-core@lists.linux.dev \
--cc=kwilczynski@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=nova-gpu@lists.linux.dev \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=simona@ffwll.ch \
--cc=tamird@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.