From 11dba56a3f44c688306b7981589254f25c789a6c Mon Sep 17 00:00:00 2001 From: itycodes Date: Tue, 5 Nov 2024 12:52:31 +0100 Subject: [PATCH] Fix tiling fetching and make GemHandle !Clone We thought that libc::ioctl would return the result of the ioctl syscall, but instead it returns -1 on failure and sets errno. GemHandle shouldn't be clone, since dropping any cloned instance will invalidate all instances. --- src/gpu/i915/mod.rs | 8 ++++---- src/uapi/i915/mod.rs | 17 ++++++++++++----- src/uapi/mod.rs | 2 +- tests/tests_i915_gpu.rs | 18 ++++++++++++++++-- tests/tests_raw.rs | 6 +++--- tests/tests_uapi.rs | 3 ++- 6 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/gpu/i915/mod.rs b/src/gpu/i915/mod.rs index 9a39590..02d98d9 100644 --- a/src/gpu/i915/mod.rs +++ b/src/gpu/i915/mod.rs @@ -13,7 +13,7 @@ pub struct DrmDeviceNode { pub path: Option, } -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct GemHandle<'a> { pub handle: DrmGemHandle, pub node: &'a DrmDeviceNode, @@ -39,12 +39,12 @@ impl GemHandle<'_> { }; return Ok(res); } else { - return Err(is_valid.err().unwrap_or(GemIoctlError::PermissionDenied)); + return Err(is_valid.err().unwrap_or(GemIoctlError::InvalidHandle)); } } pub fn close(self) -> Result<(), i32> { - return uapi::i915::close_gem(self.node.fd.as_raw_fd(), self.handle.clone()); + return unsafe { uapi::i915::close_gem_ref(self.node.fd.as_raw_fd(), &self.handle) }; } pub fn has_tiling(&self) -> Result { @@ -59,7 +59,7 @@ impl GemHandle<'_> { impl Drop for GemHandle<'_> { fn drop(&mut self) { // Ignoring the close failing as an invalid Gem handle's drop is a no-op - _ = uapi::i915::close_gem(self.node.fd.as_raw_fd(), self.handle.clone()); + _ = unsafe { uapi::i915::close_gem_ref(self.node.fd.as_raw_fd(), &self.handle) }; } } diff --git a/src/uapi/i915/mod.rs b/src/uapi/i915/mod.rs index 7d05da2..22d622f 100644 --- a/src/uapi/i915/mod.rs +++ b/src/uapi/i915/mod.rs @@ -29,7 +29,7 @@ pub struct EngineInfo { pub capabilities: u64, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq)] pub struct DrmGemHandle { pub handle: u32, } @@ -180,7 +180,7 @@ pub fn make_gem(fd: RawFd, size: u64) -> Option { } } -pub fn close_gem(fd: RawFd, handle: DrmGemHandle) -> Result<(), i32> { +pub unsafe fn close_gem_ref(fd: RawFd, handle: &DrmGemHandle) -> Result<(), i32> { unsafe { let mut close = native::drm_gem_close { handle: handle.handle, @@ -194,6 +194,12 @@ pub fn close_gem(fd: RawFd, handle: DrmGemHandle) -> Result<(), i32> { } } +pub fn close_gem(fd: RawFd, handle: DrmGemHandle) -> Result<(), i32> { + unsafe { + close_gem_ref(fd, &handle) + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GemIoctlError { InvalidHandle, @@ -210,7 +216,8 @@ pub fn gem_has_tiling(fd: RawFd, handle: &DrmGemHandle) -> Result Ok(true), libc::ENOENT => Err(GemIoctlError::InvalidHandle), libc::EPERM => Err(GemIoctlError::PermissionDenied), @@ -226,11 +233,11 @@ pub fn gem_is_valid(fd: RawFd, handle: &DrmGemHandle) -> Result 0); assert!(i915::gem_is_valid(node.fd.as_raw_fd(), &gem).unwrap()); - i915::close_gem(node.fd.as_raw_fd(), gem.clone()).expect("Failed to close gem"); + let tmp = i915::DrmGemHandle { handle: gem.handle }; + i915::close_gem(node.fd.as_raw_fd(), tmp).expect("Failed to close gem"); assert!(!i915::gem_is_valid(node.fd.as_raw_fd(), &gem).unwrap()); let invalid_fd = File::open("/dev/null").expect("Failed to open /dev/null"); assert!(i915::make_gem(invalid_fd.as_raw_fd(), 4096).is_none());