On Thu, Oct 16, 2025 at 05:08:15PM -0400, Lyude Paul wrote: > In the future we're going to be introducing more GEM object types in rust > then just gem::Object<T>. Since all types of GEM objects have refcounting, > let's introduce a macro that we can use in the gem crate in order to copy > this boilerplate implementation for each type: impl_aref_for_gem_obj!(). > > Signed-off-by: Lyude Paul <[email protected]> > --- > rust/kernel/drm/gem/mod.rs | 53 +++++++++++++++++++++++++++----------- > 1 file changed, 38 insertions(+), 15 deletions(-) > > diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs > index 20c2769a8c9d6..981fbb931e952 100644 > --- a/rust/kernel/drm/gem/mod.rs > +++ b/rust/kernel/drm/gem/mod.rs > @@ -15,6 +15,43 @@ > }; > use core::{ops::Deref, ptr::NonNull}; > > +/// A macro for implementing [`AlwaysRefCounted`] for any GEM object type. > +/// > +/// Since all GEM objects use the same refcounting scheme. > +macro_rules! impl_aref_for_gem_obj { > + ( > + impl $( <$( $tparam_id:ident ),+> )? for $type:ty > + $( > + where > + $( $bind_param:path : $bind_trait:path ),+ > + )? > + ) => { > + // SAFETY: All gem objects are refcounted > + unsafe impl $( <$( $tparam_id ),+> )? crate::types::AlwaysRefCounted > for $type > + $( > + where > + $( $bind_param : $bind_trait ),+ > + )? > + { > + fn inc_ref(&self) { > + // SAFETY: The existence of a shared reference guarantees > that the refcount is > + // non-zero. > + unsafe { bindings::drm_gem_object_get(self.as_raw()) }; > + } > + > + unsafe fn dec_ref(obj: core::ptr::NonNull<Self>) { > + // SAFETY: `obj` is a valid pointer to an `Object<T>`. > + let obj = unsafe { obj.as_ref() }; > + > + // SAFETY: The safety requirements guarantee that the > refcount is non-zero. > + unsafe { bindings::drm_gem_object_put(obj.as_raw()) };
I would prefer to move the call to `.as_raw()` to the `let obj` line so that the reference more clearly expires before the call to `drm_gem_object_put()`. The reference must not exist during the call to `drm_gem_object_put()`. > + } > + } > + }; > +} > + > +pub(crate) use impl_aref_for_gem_obj; The usual way to export macros outside the current file is: 1. Annotated with #[macro_export] 2. Export with `pub use impl_aref_for_gem_obj` Alice
