From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from sender4-op-o11.zoho.com (sender4-op-o11.zoho.com [136.143.188.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 719E83F12C0; Wed, 8 Jul 2026 15:16:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.11 ARC-Seal:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783523777; cv=pass; b=MjXVhSAqkxAR1KuEefAgrJp5hTZSAD67AXOs37Xnd66zx3CJct9pW7m2o8BakL1ThAAF5PB8iMXLmfAm/PmOo30kaOLNo/JTK9szQzCsJrYuK4KwS8w9fAIRpeVVIWE1eWqlYKo7xU/5oDe0ESN/fcQLu0Q8LdJPTCoh6ypj7Bs= ARC-Message-Signature:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783523777; c=relaxed/simple; bh=Iqkz9HZz7KsJqF6xvtRqT8xxwG+y4KVbP4uJohB9BWs=; h=Content-Type:Mime-Version:Subject:From:In-Reply-To:Date:Cc: Message-Id:References:To; b=QatHFlcHTBOo7htkq15b5L5WJ+neDFPSUK6GCRE7kMmcwxUiq8JM5VWAmOxdK7IQ0twYa8r26cOu96Qm3aWjK2MmoOxB8dTUOATVZSVsBdRlBDRP9E9FICVusyi0j9qr4RpRsMkQ6255q/Lu7VOFRLgqqOUS5HWL+WWjoq6gO2k= ARC-Authentication-Results:i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=daniel.almeida@collabora.com header.b=kEQVPxM2; arc=pass smtp.client-ip=136.143.188.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=daniel.almeida@collabora.com header.b="kEQVPxM2" ARC-Seal: i=1; a=rsa-sha256; t=1783523745; cv=none; d=zohomail.com; s=zohoarc; b=Igr8wTpfjpo1ZHqfHQn/lVnKM79U43R4E1eSVy71wQBDvHXW+bF2eW4ui7Wlm05zH+F72ZB1/Z8/x/j2BjCf6ilcdsUjooa7PMNX2Itz8G6jjHMaqhORMJ57RCIwSpetHbyI/YisCdVWgJJ+Jkg9KMKGe9UypP5HMpFPa+hUgoc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783523745; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=X1plbi+Oxfx02jtUPa4CfsK/IllRKlSLbG1pvpCqSpQ=; b=ktkjpgWkVW6XS4KQ16E5h2wy3zjPg33F3Disl5c7Xbo6Ak/eJHWeP+MTTNCv/kUnYxsakGAJc4kX9AIFBxOw9FF7H72JZo1sGw/y8N5mUnV7WnyroupyOdtSyfuOrKdMIplwZp2uY3xAbF+J1yhiZ/KCEPV37ZCNJg+jiZbtOe4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=daniel.almeida@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1783523745; s=zohomail; d=collabora.com; i=daniel.almeida@collabora.com; h=Content-Type:Mime-Version:Subject:Subject:From:From:In-Reply-To:Date:Date:Cc:Cc:Content-Transfer-Encoding:Message-Id:Message-Id:References:To:To:Reply-To; bh=X1plbi+Oxfx02jtUPa4CfsK/IllRKlSLbG1pvpCqSpQ=; b=kEQVPxM223LBIzrF2IQm1wNUlGBrh7MiW/mQZVoJUUrpCmGJaJANC3xJZOK2YDrv xnEBPy87uWH2C/WN4gbtJqhZyHIrU5COGHHkBOurTwH2t2OlYhQJka3vJWns6loEqZg 9HOXk3Qw8egDZvS6KrbvTfVp3KU8Ghu9DBnuGY74= Received: by mx.zohomail.com with SMTPS id 1783523742904701.646089296638; Wed, 8 Jul 2026 08:15:42 -0700 (PDT) Content-Type: text/plain; charset=us-ascii Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3826.700.81\)) Subject: Re: [PATCH v6 12/20] rust: io: move `Io` methods to extension trait From: Daniel Almeida In-Reply-To: <20260706-io_projection-v6-12-72cd5d055d54@garyguo.net> Date: Wed, 8 Jul 2026 12:15:23 -0300 Cc: Alice Ryhl , Greg Kroah-Hartman , "Rafael J. Wysocki" , Miguel Ojeda , Boqun Feng , =?utf-8?Q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Trevor Gross , Tamir Duberstein , =?utf-8?Q?Onur_=C3=96zkan?= , Bjorn Helgaas , =?utf-8?Q?Krzysztof_Wilczy=C5=84ski?= , Abdiel Janulgue , Robin Murphy , Alexandre Courbot , David Airlie , Simona Vetter , Michal Wilczynski , =?utf-8?Q?Uwe_Kleine-K=C3=B6nig?= , Danilo Krummrich , driver-core@lists.linux.dev, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, nova-gpu@lists.linux.dev, dri-devel@lists.freedesktop.org, linux-pwm@vger.kernel.org Content-Transfer-Encoding: quoted-printable Message-Id: References: <20260706-io_projection-v6-0-72cd5d055d54@garyguo.net> <20260706-io_projection-v6-12-72cd5d055d54@garyguo.net> To: Gary Guo X-Mailer: Apple Mail (2.3826.700.81) X-ZohoMailClient: External > On 6 Jul 2026, at 09:44, Gary Guo wrote: >=20 > `Io` trait now has a single required method with many more provided > methods. Provided methods may want to rely on their implementations to = not > be arbitrarily overridden by implementers for correctness or = soundness. > A good example is the `size` method, it may be relied by unsafe code = and > thus must be consistent with the metadata obtained from `as_ptr`. >=20 > Thus, create a new trait to host `size` method, extract existing = provided > methods to the new trait, and provide a blanket implementation. This > pattern is used extensively in userspace Rust libraries e.g. `tokio` = where > `AsyncRead` has minimum methods and `AsyncReadExt` is what users = mostly > interact with. >=20 > To avoid changing all user imports, the base trait is renamed to = `IoBase` > and the newly added trait takes the existing `Io` name. >=20 > Reviewed-by: Alexandre Courbot > Suggested-by: Danilo Krummrich > Signed-off-by: Gary Guo > --- > rust/kernel/devres.rs | 3 ++- > rust/kernel/io.rs | 34 ++++++++++++++++++++++++---------- > rust/kernel/io/mem.rs | 6 +++--- > rust/kernel/pci/io.rs | 6 +++--- > 4 files changed, 32 insertions(+), 17 deletions(-) >=20 > diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs > index 3545ffc5345d..6e0b845b229b 100644 > --- a/rust/kernel/devres.rs > +++ b/rust/kernel/devres.rs > @@ -68,6 +68,7 @@ struct Inner { > /// devres::Devres, > /// io::{ > /// Io, > +/// IoBase, > /// Mmio, > /// MmioRaw, > /// MmioBackend, > @@ -105,7 +106,7 @@ struct Inner { > /// } > /// } > /// > -/// impl<'a, const SIZE: usize> Io<'a> for &'a IoMem { > +/// impl<'a, const SIZE: usize> IoBase<'a> for &'a IoMem { > /// type Backend =3D MmioBackend; > /// type Target =3D Region; > /// > diff --git a/rust/kernel/io.rs b/rust/kernel/io.rs > index c7533d605678..ab970e8b2e78 100644 > --- a/rust/kernel/io.rs > +++ b/rust/kernel/io.rs > @@ -223,7 +223,7 @@ fn io_view<'a, IO: Io<'a>, U>( > /// operation. > pub trait IoBackend { > /// View type for this I/O backend. > - type View<'a, T: ?Sized + KnownSize>: Io<'a, Backend =3D Self, = Target =3D T>; > + type View<'a, T: ?Sized + KnownSize>: IoBase<'a, Backend =3D = Self, Target =3D T>; >=20 > /// Convert a `view` to a raw pointer for projection. > /// > @@ -309,15 +309,12 @@ fn offset(self) -> usize { > /// Types implementing this trait (e.g. MMIO BARs or PCI config = regions) > /// can perform I/O operations on regions of memory. > /// > -/// The [`Io`] trait provides: > -/// - Method to convert into [`IoBackend::View`]. > -/// - Helper methods for offset validation and address calculation > -/// - Fallible (runtime checked) accessors for different data widths > -/// > -/// Which I/O methods are available depends on the associated = [`IoBackend`] implementation. > +/// This trait defines which backend shall be used for I/O operations = and provides a method to > +/// convert into [`IoBackend::View`]. Users should use the [`Io`] = trait which provides the actual > +/// methods to perform I/O operations. > /// > /// This should be implemented on cheaply copyable handles, such as = references or view types. > -pub trait Io<'a>: Copy { > +pub trait IoBase<'a>: Copy { > /// Type that defines all I/O operations. > type Backend: IoBackend; >=20 > @@ -326,6 +323,21 @@ pub trait Io<'a>: Copy { >=20 > /// Return a view that covers the full region. > fn as_view(self) -> ::View<'a, = Self::Target>; > +} > + > +/// Extension trait to provide I/O operation methods to types that = implement [`IoBase`]. > +/// > +/// This trait provides: > +/// - Helper methods for offset validation and address calculation > +/// - Fallible (runtime checked) accessors for different data widths > +/// > +/// Which I/O methods are available depends on the associated = [`IoBackend`] implementation. > +pub trait Io<'a>: IoBase<'a> { > + /// Returns the size of this I/O region. > + #[inline] > + fn size(self) -> usize { > + KnownSize::size(Self::Backend::as_ptr(self.as_view())) > + } >=20 > /// Fallible 8-bit read with runtime bounds check. > #[inline(always)] > @@ -779,6 +791,8 @@ fn update(self, location: L, f: F) > } > } >=20 IIUC this is what makes the methods non-overridable? If so, consider leaving a comment? i.e.: // Provided methods may want to rely on their implementations to not be // arbitrarily overridden by implementers for correctness or soundness, = thus, // enforce it through this blanket implementation Makes it easier to maintain later IMHO. > +impl<'a, T: IoBase<'a>> Io<'a> for T {} > + > /// A view of memory-mapped I/O region. > /// > /// # Invariant > @@ -819,7 +833,7 @@ unsafe impl Send for Mmio<'_, T> = {} > // SAFETY: `Mmio<'_, T>` is conceptually `&T` but in I/O memory. > unsafe impl Sync for Mmio<'_, T> {} >=20 > -impl<'a, T: ?Sized + KnownSize> Io<'a> for Mmio<'a, T> { > +impl<'a, T: ?Sized + KnownSize> IoBase<'a> for Mmio<'a, T> { > type Backend =3D MmioBackend; > type Target =3D T; >=20 > @@ -920,7 +934,7 @@ unsafe fn project_view<'a, T: ?Sized + KnownSize, = U: ?Sized + KnownSize>( > } > } >=20 > -impl<'a, T: ?Sized + KnownSize> Io<'a> for RelaxedMmio<'a, T> { > +impl<'a, T: ?Sized + KnownSize> IoBase<'a> for RelaxedMmio<'a, T> { > type Backend =3D RelaxedMmioBackend; > type Target =3D T; >=20 > diff --git a/rust/kernel/io/mem.rs b/rust/kernel/io/mem.rs > index d9b3189d09b4..e95b769ebe47 100644 > --- a/rust/kernel/io/mem.rs > +++ b/rust/kernel/io/mem.rs > @@ -14,7 +14,7 @@ > Region, > Resource, // > }, > - Io, > + IoBase, > Mmio, > MmioBackend, > MmioRaw, // > @@ -210,7 +210,7 @@ pub fn into_devres(self) -> = Result>> { > } > } >=20 > -impl<'a, const SIZE: usize> Io<'a> for &'a ExclusiveIoMem<'_, SIZE> { > +impl<'a, const SIZE: usize> IoBase<'a> for &'a ExclusiveIoMem<'_, = SIZE> { > type Backend =3D MmioBackend; > type Target =3D super::Region; >=20 > @@ -292,7 +292,7 @@ fn drop(&mut self) { > } > } >=20 > -impl<'a, const SIZE: usize> Io<'a> for &'a IoMem<'_, SIZE> { > +impl<'a, const SIZE: usize> IoBase<'a> for &'a IoMem<'_, SIZE> { > type Backend =3D MmioBackend; > type Target =3D super::Region; >=20 > diff --git a/rust/kernel/pci/io.rs b/rust/kernel/pci/io.rs > index 4be33ecb4192..4d1d0afdc491 100644 > --- a/rust/kernel/pci/io.rs > +++ b/rust/kernel/pci/io.rs > @@ -8,8 +8,8 @@ > device, > devres::Devres, > io::{ > - Io, > IoBackend, > + IoBase, > IoCapable, > Mmio, > MmioBackend, > @@ -144,7 +144,7 @@ fn io_write(view: ConfigSpace<'_, $ty>, value: = $ty) { > impl_config_space_io_capable!(u16, pci_read_config_word, = pci_write_config_word); > impl_config_space_io_capable!(u32, pci_read_config_dword, = pci_write_config_dword); >=20 > -impl<'a, T: ?Sized + KnownSize> Io<'a> for ConfigSpace<'a, T> { > +impl<'a, T: ?Sized + KnownSize> IoBase<'a> for ConfigSpace<'a, T> { > type Backend =3D ConfigSpaceBackend; > type Target =3D T; >=20 > @@ -267,7 +267,7 @@ fn drop(&mut self) { > } > } >=20 > -impl<'a, const SIZE: usize> Io<'a> for &'a Bar<'_, SIZE> { > +impl<'a, const SIZE: usize> IoBase<'a> for &'a Bar<'_, SIZE> { > type Backend =3D MmioBackend; > type Target =3D crate::io::Region; >=20 >=20 > --=20 > 2.54.0 >=20 Reviewed-by: Daniel Almeida