Re: [PATCH 2/8] rust: io: generalize `Mmio` to arbitrary type
From: Gary Guo
Date: Thu Apr 02 2026 - 09:07:06 EST
On Thu Mar 26, 2026 at 6:23 PM GMT, Andreas Hindborg wrote:
> "Gary Guo" <gary@xxxxxxxxxxx> writes:
>
>> On Thu Mar 26, 2026 at 1:04 PM GMT, Andreas Hindborg wrote:
>>> "Gary Guo" <gary@xxxxxxxxxx> writes:
>>>
>>>> From: Gary Guo <gary@xxxxxxxxxxx>
>>>>
>>>> Currently, `io::Mmio` always represent an untyped region of a compile-time
>>>> known minimum size, which is roughly equivalent to `void __iomem*` (but
>>>> with bound checks). However, it is useful to also be to represent I/O
>>>> memory of a specific type, e.g. `u32 __iomem*` or `struct foo __iomem*`.
>>>>
>>>> Thus, make `Mmio` generic on arbitrary `T`, where `T` is a sized type, or a
>>>> DST that implements `KnownSize`. Similar to the `MmioRaw` change, the
>>>> existing behaviour is preserved in the form of `Mmio<Region<SIZE>>`. This
>>>> change brings the MMIO closer to the DMA coherent allocation types that we
>>>> have, which is already typed.
>>>>
>>>> To be able to implement `IoKnownSize`, add a `MIN_SIZE` constant to
>>>> `KnownSize` trait to represent compile-time known minimum size of a
>>>> specific type.
>>>>
>>>> Signed-off-by: Gary Guo <gary@xxxxxxxxxxx>
>>>> ---
>>>> rust/kernel/devres.rs | 2 +-
>>>> rust/kernel/io.rs | 63 ++++++++++++++++++++++----------------
>>>> rust/kernel/io/mem.rs | 4 +--
>>>> rust/kernel/io/poll.rs | 6 ++--
>>>> rust/kernel/io/register.rs | 19 +++++++-----
>>>> rust/kernel/pci/io.rs | 2 +-
>>>> rust/kernel/ptr.rs | 7 +++++
>>>> 7 files changed, 64 insertions(+), 39 deletions(-)
>>>>
>>>> diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs
>>>> index 65a4082122af..3e22c63efb98 100644
>>>> --- a/rust/kernel/devres.rs
>>>> +++ b/rust/kernel/devres.rs
>>>> @@ -106,7 +106,7 @@ struct Inner<T> {
>>>> /// }
>>>> ///
>>>> /// impl<const SIZE: usize> Deref for IoMem<SIZE> {
>>>> -/// type Target = Mmio<SIZE>;
>>>> +/// type Target = Mmio<Region<SIZE>>;
>>>> ///
>>>> /// fn deref(&self) -> &Self::Target {
>>>> /// // SAFETY: The memory range stored in `self` has been properly mapped in `Self::new`.
>>>> diff --git a/rust/kernel/io.rs b/rust/kernel/io.rs
>>>> index d7f2145fa9b9..5a26b1e7e533 100644
>>>> --- a/rust/kernel/io.rs
>>>> +++ b/rust/kernel/io.rs
>>>> @@ -44,6 +44,8 @@ pub struct Region<const SIZE: usize = 0> {
>>>> }
>>>>
>>>> impl<const SIZE: usize> KnownSize for Region<SIZE> {
>>>> + const MIN_SIZE: usize = SIZE;
>>>> +
>>>> #[inline(always)]
>>>> fn size(p: *const Self) -> usize {
>>>> (p as *const [u8]).len()
>>>> @@ -169,7 +171,7 @@ pub fn size(&self) -> usize {
>>>> /// }
>>>> ///
>>>> /// impl<const SIZE: usize> Deref for IoMem<SIZE> {
>>>> -/// type Target = Mmio<SIZE>;
>>>> +/// type Target = Mmio<Region<SIZE>>;
>>>> ///
>>>> /// fn deref(&self) -> &Self::Target {
>>>> /// // SAFETY: The memory range stored in `self` has been properly mapped in `Self::new`.
>>>> @@ -187,7 +189,7 @@ pub fn size(&self) -> usize {
>>>> /// # }
>>>> /// ```
>>>> #[repr(transparent)]
>>>> -pub struct Mmio<const SIZE: usize = 0>(MmioRaw<Region<SIZE>>);
>>>> +pub struct Mmio<T: ?Sized>(MmioRaw<T>);
>>>
>>> Why not have the `KnownSize` bound here? I think that would be more clear.
>>>
>>
>> There's no need to put bounds on structs unless you need them for `Drop` or use
>> of assoc types.
>
> I understand there is no technical need, but it would help communicating
> how the code is intended to work. Unless I am mistaken, T will always be
> `KnownSize`, right?
I think most users don't need to know about this. All `T: Sized` will be `T:
KnownSize`, so if you're using it with a concrete type then the bound is
already satisfied.
The same argument can be said to document
struct Coherent<T: AsBytes + FromBytes + KnownSize + ?Sized>
instead of just
struct Coherent<T: ?Sized + KnownSize>
// ^ In this case the `drop` does need `KnownSize` bound
But this just makes code more verbose as now you need to carry `?Sized` bound
everywhere.
If there's nothing other than documentation purpose I'd prefer to just leave it
out.
Best,
Gary
>
>
> Best regards,
> Andreas Hindborg