diff options
| author | Dave Airlie <airlied@redhat.com> | 2025-11-20 10:42:50 +1000 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2025-11-20 10:44:50 +1000 |
| commit | f0ded972d37150f9f889de75c9eecc5cb0730013 (patch) | |
| tree | 1cbf2650fd192cd2b10d497ada78dc55721d842a /rust/kernel/drm/gem/mod.rs | |
| parent | f3a1d69f9b388271986f4efe1fd775df15b443c1 (diff) | |
| parent | 77b686f688126a5f758b51441a03186e9eb1b0f1 (diff) | |
Merge tag 'drm-rust-next-2025-11-18' of https://gitlab.freedesktop.org/drm/rust/kernel into drm-next
Cross-subsystem Changes:
Rust
- Make slice::as_flattened usable on all supported versions of rustc.
- Add FromBytes::from_bytes_prefix() method.
Core Changes:
- Update Tyr in MAINTAINERS file.
- Remove redundant device ptr from Rust GEM object.
- Change how AlwaysRefCounted is implemented for GEM objects.
- Add deferred vm_bo cleanup to GPUVM and use it in Panthor.
Driver Changes:
Nova Core
- Introduction of bitfield! macro, with support for different storage sizes
and custom visibility.
- Introduction of safe converters between integer types for which the
conversion is lossless.
- GSP initialized up to fully booted state on Ampere.
- Use more future-proof register for GPU identification.
- Various simplifications and optimizations.
Nova
- Select NOVA_CORE.
- Depend on CONFIG_64BIT.
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Alice Ryhl <aliceryhl@google.com>
Link: https://patch.msgid.link/aRxtJC0D1pQUepF4@google.com
Diffstat (limited to 'rust/kernel/drm/gem/mod.rs')
| -rw-r--r-- | rust/kernel/drm/gem/mod.rs | 53 |
1 files changed, 24 insertions, 29 deletions
diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs index 30c853988b94..a7f682e95c01 100644 --- a/rust/kernel/drm/gem/mod.rs +++ b/rust/kernel/drm/gem/mod.rs @@ -55,26 +55,6 @@ pub trait IntoGEMObject: Sized + super::private::Sealed + AlwaysRefCounted { unsafe fn from_raw<'a>(self_ptr: *mut bindings::drm_gem_object) -> &'a Self; } -// SAFETY: All gem objects are refcounted. -unsafe impl<T: IntoGEMObject> AlwaysRefCounted for T { - 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: NonNull<Self>) { - // SAFETY: We either hold the only refcount on `obj`, or one of many - meaning that no one - // else could possibly hold a mutable reference to `obj` and thus this immutable reference - // is safe. - let obj = unsafe { obj.as_ref() }.as_raw(); - - // SAFETY: - // - The safety requirements guarantee that the refcount is non-zero. - // - We hold no references to `obj` now, making it safe for us to potentially deallocate it. - unsafe { bindings::drm_gem_object_put(obj) }; - } -} - extern "C" fn open_callback<T: DriverObject>( raw_obj: *mut bindings::drm_gem_object, raw_file: *mut bindings::drm_file, @@ -184,15 +164,13 @@ impl<T: IntoGEMObject> BaseObject for T {} /// A base GEM object. /// -/// Invariants +/// # Invariants /// /// - `self.obj` is a valid instance of a `struct drm_gem_object`. -/// - `self.dev` is always a valid pointer to a `struct drm_device`. #[repr(C)] #[pin_data] pub struct Object<T: DriverObject + Send + Sync> { obj: Opaque<bindings::drm_gem_object>, - dev: NonNull<drm::Device<T::Driver>>, #[pin] data: T, } @@ -222,9 +200,6 @@ impl<T: DriverObject> Object<T> { try_pin_init!(Self { obj: Opaque::new(bindings::drm_gem_object::default()), data <- T::new(dev, size), - // INVARIANT: The drm subsystem guarantees that the `struct drm_device` will live - // as long as the GEM object lives. - dev: dev.into(), }), GFP_KERNEL, )?; @@ -247,9 +222,13 @@ impl<T: DriverObject> Object<T> { /// Returns the `Device` that owns this GEM object. pub fn dev(&self) -> &drm::Device<T::Driver> { - // SAFETY: The DRM subsystem guarantees that the `struct drm_device` will live as long as - // the GEM object lives, hence the pointer must be valid. - unsafe { self.dev.as_ref() } + // SAFETY: + // - `struct drm_gem_object.dev` is initialized and valid for as long as the GEM + // object lives. + // - The device we used for creating the gem object is passed as &drm::Device<T::Driver> to + // Object::<T>::new(), so we know that `T::Driver` is the right generic parameter to use + // here. + unsafe { drm::Device::from_raw((*self.as_raw()).dev) } } fn as_raw(&self) -> *mut bindings::drm_gem_object { @@ -273,6 +252,22 @@ impl<T: DriverObject> Object<T> { } } +// SAFETY: Instances of `Object<T>` are always reference-counted. +unsafe impl<T: DriverObject> crate::types::AlwaysRefCounted for Object<T> { + 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: 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()) } + } +} + impl<T: DriverObject> super::private::Sealed for Object<T> {} impl<T: DriverObject> Deref for Object<T> { |