Skip to content

Commit 9bc2928

Browse files
hoshinolinamarcan
authored andcommitted
rust: drm: device: Convert Device to AlwaysRefCounted
Switch from being a refcount wrapper itself to a transparent wrapper around `bindings::drm_device`. The refcounted type then becomes ARef<Device<T>>. Signed-off-by: Asahi Lina <lina@asahilina.net>
1 parent 6f4ad4c commit 9bc2928

1 file changed

Lines changed: 21 additions & 18 deletions

File tree

rust/kernel/drm/gem/shmem.rs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::{
1212
use core::{
1313
marker::PhantomData,
1414
mem,
15-
mem::{ManuallyDrop, MaybeUninit},
15+
mem::MaybeUninit,
1616
ops::{Deref, DerefMut},
1717
ptr::addr_of_mut,
1818
slice,
@@ -70,23 +70,15 @@ pub struct Object<T: DriverObject> {
7070
obj: bindings::drm_gem_shmem_object,
7171
// The DRM core ensures the Device exists as long as its objects exist, so we don't need to
7272
// manage the reference count here.
73-
dev: ManuallyDrop<device::Device<T::Driver>>,
73+
dev: *const bindings::drm_device,
74+
#[pin]
7475
inner: T,
7576
}
7677

7778
unsafe extern "C" fn gem_create_object<T: DriverObject>(
78-
raw_dev: *mut bindings::drm_device,
79+
dev: *mut bindings::drm_device,
7980
size: usize,
8081
) -> *mut bindings::drm_gem_object {
81-
// SAFETY: GEM ensures the device lives as long as its objects live,
82-
// so we can conjure up a reference from thin air and never drop it.
83-
let dev = ManuallyDrop::new(unsafe { device::Device::from_raw(raw_dev) });
84-
85-
let inner = match T::new(&*dev, size) {
86-
Ok(v) => v,
87-
Err(e) => return e.to_ptr(),
88-
};
89-
9082
let p = unsafe {
9183
bindings::krealloc(
9284
core::ptr::null(),
@@ -99,10 +91,19 @@ unsafe extern "C" fn gem_create_object<T: DriverObject>(
9991
return ENOMEM.to_ptr();
10092
}
10193

102-
// SAFETY: p is valid as long as the alloc succeeded
103-
unsafe {
104-
addr_of_mut!((*p).dev).write(dev);
105-
addr_of_mut!((*p).inner).write(inner);
94+
let init = try_pin_init!(Object {
95+
obj <- init::zeroed(),
96+
// SAFETY: GEM ensures the device lives as long as its objects live
97+
inner <- T::new(unsafe { device::Device::borrow(dev)}, size),
98+
dev,
99+
});
100+
101+
// SAFETY: p is a valid pointer to an uninitialized Object<T>.
102+
if let Err(e) = unsafe { init.__pinned_init(p) } {
103+
// SAFETY: p is a valid pointer from `krealloc` and __pinned_init guarantees we can dealloc it.
104+
unsafe { bindings::kfree(p as *mut _) };
105+
106+
return e.to_ptr();
106107
}
107108

108109
// SAFETY: drm_gem_shmem_object is safe to zero-init, and
@@ -160,7 +161,7 @@ impl<T: DriverObject> Object<T> {
160161
pub fn new(dev: &device::Device<T::Driver>, size: usize) -> Result<gem::UniqueObjectRef<Self>> {
161162
// SAFETY: This function can be called as long as the ALLOC_OPS are set properly
162163
// for this driver, and the gem_create_object is called.
163-
let p = unsafe { bindings::drm_gem_shmem_create(dev.raw() as *mut _, size) };
164+
let p = unsafe { bindings::drm_gem_shmem_create(dev.raw_mut(), size) };
164165
let p = crate::container_of!(p, Object<T>, obj) as *mut _;
165166

166167
// SAFETY: The gem_create_object callback ensures this is a valid Object<T>,
@@ -172,7 +173,9 @@ impl<T: DriverObject> Object<T> {
172173

173174
/// Returns the `Device` that owns this GEM object.
174175
pub fn dev(&self) -> &device::Device<T::Driver> {
175-
&self.dev
176+
// SAFETY: GEM ensures that the device outlives its objects, so we can
177+
// just borrow here.
178+
unsafe { device::Device::borrow(self.dev) }
176179
}
177180

178181
/// Creates (if necessary) and returns a scatter-gather table of DMA pages for this object.

0 commit comments

Comments
 (0)