[PATCH v7 04/10] rust: sizes: implement SizeConstants for Alignment
Eliot Courtney <[email protected]>
| Newsgroups | dev.linux.lists.nova-gpu,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-kernel,org.kernel.vger.rust-for-linux |
|---|---|
| Message-ID | <[email protected]> |
Currently, constructing an alignment is quite verbose: `Alignment::new::<8>()` It's unfortunate because it disincentivizes using it at interface boundaries. Implement `SizeConstants` for `Alignment` and add some more size constants (mirroring include/linux/sizes.h) so we can write e.g. `Alignment::SZ_8` instead. Link: https://lore.kernel.org/an4xDp29VX8Am0uR@yury Signed-off-by: Eliot Courtney <[email protected]> --- rust/kernel/sizes.rs | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/rust/kernel/sizes.rs b/rust/kernel/sizes.rs index 521b2b38bfe7..825d6b566952 100644 --- a/rust/kernel/sizes.rs +++ b/rust/kernel/sizes.rs @@ -13,6 +13,11 @@ //! these constants as [`u64`] (or [`u32`]) rather than [`usize`], because //! device address spaces are sized independently of the CPU pointer width. //! +//! The trait is also implemented for [`Alignment`], providing each size as a +//! compile-time validated alignment. +//! +//! [`Alignment`]: crate::ptr::Alignment +//! //! # Examples //! //! ``` @@ -35,6 +40,26 @@ macro_rules! define_sizes { ($($type:ty),* $(,)?) => { define_sizes!(@internal [$($type),*] + /// `0x0000_0001`. + SZ_1, + /// `0x0000_0002`. + SZ_2, + /// `0x0000_0004`. + SZ_4, + /// `0x0000_0008`. + SZ_8, + /// `0x0000_0010`. + SZ_16, + /// `0x0000_0020`. + SZ_32, + /// `0x0000_0040`. + SZ_64, + /// `0x0000_0080`. + SZ_128, + /// `0x0000_0100`. + SZ_256, + /// `0x0000_0200`. + SZ_512, /// `0x0000_0400`. SZ_1K, /// `0x0000_0800`. @@ -85,6 +110,7 @@ macro_rules! define_sizes { (@internal [$($type:ty),*] $($names_and_metas:tt)*) => { define_sizes!(@consts_and_trait $($names_and_metas)*); define_sizes!(@impls [$($type),*] $($names_and_metas)*); + define_sizes!(@impl_alignment $($names_and_metas)*); }; (@consts_and_trait $($(#[$meta:meta])* $name:ident,)*) => { @@ -99,13 +125,22 @@ macro_rules! define_sizes { /// choose the width that matches their hardware. All `SZ_*` values fit /// in a [`u32`], so all implementations are lossless. /// + /// Also implemented for [`Alignment`], providing each size as a + /// compile-time validated alignment. + /// + /// [`Alignment`]: crate::ptr::Alignment + /// /// # Examples /// /// ``` - /// use kernel::sizes::SizeConstants; + /// use kernel::{ + /// ptr::Alignment, + /// sizes::SizeConstants, // + /// }; /// /// let gpu_heap = 14 * u64::SZ_1M; /// let mmio_window = u32::SZ_16M; + /// let page_align = Alignment::SZ_4K; /// ``` pub trait SizeConstants { $( @@ -117,6 +152,16 @@ pub trait SizeConstants { (@impls [] $($(#[$meta:meta])* $name:ident,)*) => {}; + (@impl_alignment $($(#[$meta:meta])* $name:ident,)*) => { + impl SizeConstants for crate::ptr::Alignment { + $( + $(#[$meta])* + // A non-power-of-two constant will fail the build here if used. + const $name: Self = crate::ptr::Alignment::new_checked(self::$name).unwrap(); + )* + } + }; + (@impls [$first:ty $(, $rest:ty)*] $($(#[$meta:meta])* $name:ident,)*) => { impl SizeConstants for $first { $( -- 2.55.0