Fix tiling fetching

We thought that libc::ioctl would return the result of the ioctl
syscall, but instead it returns -1 on failure and sets errno.
itycodes 2 weeks ago
parent ca4fa2aeab
commit 58295d22d8

@ -13,7 +13,7 @@ pub struct DrmDeviceNode {
pub path: Option<OsString>, pub path: Option<OsString>,
} }
#[derive(Debug, Clone)] #[derive(Debug)]
pub struct GemHandle<'a> { pub struct GemHandle<'a> {
pub handle: DrmGemHandle, pub handle: DrmGemHandle,
pub node: &'a DrmDeviceNode, pub node: &'a DrmDeviceNode,
@ -39,12 +39,12 @@ impl GemHandle<'_> {
}; };
return Ok(res); return Ok(res);
} else { } 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> { 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<bool, uapi::i915::GemIoctlError> { pub fn has_tiling(&self) -> Result<bool, uapi::i915::GemIoctlError> {
@ -59,7 +59,7 @@ impl GemHandle<'_> {
impl Drop for GemHandle<'_> { impl Drop for GemHandle<'_> {
fn drop(&mut self) { fn drop(&mut self) {
// Ignoring the close failing as an invalid Gem handle's drop is a no-op // 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) };
} }
} }

@ -29,7 +29,7 @@ pub struct EngineInfo {
pub capabilities: u64, pub capabilities: u64,
} }
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub struct DrmGemHandle { pub struct DrmGemHandle {
pub handle: u32, pub handle: u32,
} }
@ -180,7 +180,7 @@ pub fn make_gem(fd: RawFd, size: u64) -> Option<DrmGemHandle> {
} }
} }
pub fn close_gem(fd: RawFd, handle: DrmGemHandle) -> Result<(), i32> { pub unsafe fn close_gem_ref(fd: RawFd, handle: &DrmGemHandle) -> Result<(), i32> {
unsafe { unsafe {
let mut close = native::drm_gem_close { let mut close = native::drm_gem_close {
handle: handle.handle, 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)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GemIoctlError { pub enum GemIoctlError {
InvalidHandle, InvalidHandle,
@ -210,7 +216,8 @@ pub fn gem_has_tiling(fd: RawFd, handle: &DrmGemHandle) -> Result<bool, GemIoctl
phys_swizzle_mode: 0, phys_swizzle_mode: 0,
}; };
let res = libc::ioctl(fd, native::DRM_IOCTL_I915_GEM_GET_TILING, &mut tiling); let res = libc::ioctl(fd, native::DRM_IOCTL_I915_GEM_GET_TILING, &mut tiling);
match -res { let errno = *libc::__errno_location();
match errno {
0 => Ok(true), 0 => Ok(true),
libc::ENOENT => Err(GemIoctlError::InvalidHandle), libc::ENOENT => Err(GemIoctlError::InvalidHandle),
libc::EPERM => Err(GemIoctlError::PermissionDenied), libc::EPERM => Err(GemIoctlError::PermissionDenied),
@ -226,11 +233,11 @@ pub fn gem_is_valid(fd: RawFd, handle: &DrmGemHandle) -> Result<bool, GemIoctlEr
return Ok(true); return Ok(true);
} }
// For some reason the kernel returns -EPERM instead of -ENOENT when the handle is invalid... if res.is_err() && res.unwrap_err() == GemIoctlError::InvalidHandle {
if res.is_err() && res.unwrap_err() == GemIoctlError::PermissionDenied {
return Ok(false); return Ok(false);
} }
println!("Unexpected error: {:?}", res.unwrap_err());
return Err(res.unwrap_err()); return Err(res.unwrap_err());
} }

@ -2,7 +2,7 @@
use std::os::fd::RawFd; use std::os::fd::RawFd;
use std::ffi::{CStr, OsString}; use std::ffi::{CStr, OsString};
use std::os::unix::ffi::{OsStrExt, OsStringExt}; use std::os::unix::ffi::OsStringExt;
use std::vec; use std::vec;
use libc; use libc;

@ -1,5 +1,6 @@
use intel_gpu::*; use intel_gpu::*;
use gpu::i915; use gpu::i915;
use uapi::i915::DrmGemHandle;
use std::os::fd::{AsRawFd, OwnedFd, RawFd}; use std::os::fd::{AsRawFd, OwnedFd, RawFd};
use std::fs::File; use std::fs::File;
use std::path::Path; use std::path::Path;
@ -89,17 +90,30 @@ fn test_i915_gpu_get_param() {
fn test_i915_gpu_gem_lifecycle() { fn test_i915_gpu_gem_lifecycle() {
let device = i915::find_device().expect("Failed to find i915 device"); let device = i915::find_device().expect("Failed to find i915 device");
let gem = i915::GemHandle::new(&device.node, 4096).expect("Failed to create gem handle"); let gem = i915::GemHandle::new(&device.node, 4096).expect("Failed to create gem handle");
let tmp = gem.handle.clone(); let tmp = DrmGemHandle { handle: gem.handle.handle };
assert!(gem.is_valid().unwrap()); assert!(gem.is_valid().unwrap());
drop(gem); drop(gem);
assert!(i915::GemHandle::from_handle(&device.node, tmp).is_err()); assert!(i915::GemHandle::from_handle(&device.node, tmp).is_err());
} }
#[test]
fn test_i915_gpu_gem_close() {
let device = i915::find_device().expect("Failed to find i915 device");
let gem = i915::GemHandle::new(&device.node, 4096).expect("Failed to create gem handle");
let tmp_handle = DrmGemHandle { handle: gem.handle.handle };
let tmp = i915::GemHandle::from_handle(&device.node, tmp_handle)
.expect("Failed to create gem handle from handle");
assert!(gem.is_valid().unwrap());
gem.close().expect("Failed to close gem");
assert!(!tmp.is_valid().unwrap());
}
#[test] #[test]
fn test_i915_gpu_gem_from_handle() { fn test_i915_gpu_gem_from_handle() {
let device = i915::find_device().expect("Failed to find i915 device"); let device = i915::find_device().expect("Failed to find i915 device");
let gem = i915::GemHandle::new(&device.node, 4096).expect("Failed to create gem handle"); let gem = i915::GemHandle::new(&device.node, 4096).expect("Failed to create gem handle");
let tmp = gem.handle.clone(); let tmp = DrmGemHandle { handle: gem.handle.handle };
let gem_2 = i915::GemHandle::from_handle(&device.node, tmp).expect("Failed to create gem handle from handle"); let gem_2 = i915::GemHandle::from_handle(&device.node, tmp).expect("Failed to create gem handle from handle");
assert_eq!(gem.handle, gem_2.handle); assert_eq!(gem.handle, gem_2.handle);
assert!(gem.is_valid().unwrap()); assert!(gem.is_valid().unwrap());

@ -13,8 +13,8 @@ fn test_raw_drm_version() {
libc::memset(name_vec, 0, 128); libc::memset(name_vec, 0, 128);
let date_vec = libc::malloc(128); let date_vec = libc::malloc(128);
libc::memset(date_vec, 0, 128); libc::memset(date_vec, 0, 128);
let desc_vec = libc::malloc(128); let mut desc_vec = vec![0; 128];
libc::memset(desc_vec, 0, 128); //libc::memset(desc_vec, 0, 128);
let mut version = native::drm_version { let mut version = native::drm_version {
version_major: 0, version_major: 0,
@ -22,7 +22,7 @@ fn test_raw_drm_version() {
version_patchlevel: 0, version_patchlevel: 0,
name: name_vec as *mut i8, name: name_vec as *mut i8,
date: date_vec as *mut i8, date: date_vec as *mut i8,
desc: desc_vec as *mut i8, desc: desc_vec.as_mut_ptr() as *mut i8,
name_len: 128, name_len: 128,
date_len: 128, date_len: 128,
desc_len: 128, desc_len: 128,

@ -64,7 +64,8 @@ fn test_i915_uapi_gem_lifecycle() {
let gem = i915::make_gem(node.fd.as_raw_fd(), 4096).expect("Failed to make gem"); let gem = i915::make_gem(node.fd.as_raw_fd(), 4096).expect("Failed to make gem");
assert!(gem.handle > 0); assert!(gem.handle > 0);
assert!(i915::gem_is_valid(node.fd.as_raw_fd(), &gem).unwrap()); 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()); 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"); 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()); assert!(i915::make_gem(invalid_fd.as_raw_fd(), 4096).is_none());

Loading…
Cancel
Save