rust: drm: device: drop_in_place() the drm::Device in release()
Subsystems (3)
Danilo Krummrich
maintainerPATCH 1/1 rust: drm: device: drop_in_place() the drm::Device in release()
In drm::Device::new() we allocate with __drm_dev_alloc() and return an ARef<drm::Device>.
When the reference count of the drm::Device falls to zero, the C code automatically calls drm_dev_release(), which eventually frees the memory allocated in drm::Device::new().
However, due to that, drm::Device::drop() is never called. As a result the destructor of the user's private data, i.e. drm::Device::data is never called. Hence, fix this by calling drop_in_place() from the DRM device's release callback.
--- rust/kernel/drm/device.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
rust/kernel/drm/device.rs +11 -1
@@ -66,7 +66,7 @@ impl<T: drm::Driver> Device<T> { open: Some(drm::File::<T::File>::open_callback), postclose: Some(drm::File::<T::File>::postclose_callback), unload: None, - release: None, + release: Some(Self::release), master_set: None, master_drop: None, debugfs_init: None,
@@ -162,6 +162,16 @@ pub unsafe fn as_ref<'a>(ptr: *const bindings::drm_device) -> &'a Self {// SAFETY: `ptr` is valid by the safety requirements of this function. unsafe { &*ptr.cast () } } + +extern "C" fn release (ptr: *mut bindings::drm_device ) { +// SAFETY: `ptr` is a valid pointer to a `struct drm_device` and embedded in `Self`. +let this =unsafe {Self ::from_drm_device (ptr) }; + +// SAFETY: +// - When `release` runs it is guaranteed that there is no further access to `this`. +// - `this` is valid for dropping. +unsafe { core::ptr::drop_in_place (this) }; + } }impl <T : drm::Driver >Deref for Device <T > {
base-commit: 615cc4223fcbe1e0e6f68b8494b26bb6c08d917a
Signature · 1 line
2.50.0
Quoted 8 lines · Danilo Krummrich
In
drm::Device::new()we allocate with__drm_dev_alloc()and return an ARef<drm::Device>.When the reference count of the
drm::Devicefalls to zero, the C code automatically callsdrm_dev_release(), which eventually frees the memory allocated indrm::Device::new().
Quoted 7 lines
However, due to that,
drm::Device::drop()is never called. As a result the destructor of the user's private data, i.e.drm::Device::datais never called. Hence, fix this by callingdrop_in_place()from the DRM device's release callback.Fixes 1e4b8896c0f3 ("rust: drm: add device abstraction")Signed-off-by Danilo Krummrich <[email protected]>
Quoted 7 lines · Danilo Krummrich
In
drm::Device::new()we allocate with__drm_dev_alloc()and return an ARef<drm::Device>.When the reference count of the
drm::Devicefalls to zero, the C code automatically callsdrm_dev_release(), which eventually frees the memory allocated indrm::Device::new().
Quoted 7 lines
However, due to that,
drm::Device::drop()is never called. As a result the destructor of the user's private data, i.e.drm::Device::datais never called. Hence, fix this by callingdrop_in_place()from the DRM device's release callback.Fixes 1e4b8896c0f3 ("rust: drm: add device abstraction")Signed-off-by Danilo Krummrich <[email protected]>
Applied to drm-misc-fixes, thanks!