From: Sami Tolvanen <[email protected]> Userspace may request a cacheable CPU mapping for a buffer it accesses frequently. Accept DRM_PANTHOR_BO_WB_MMAP in bo_create and map the buffer cached when the flag is set. Coherent devices already map cached. NO_MMAP and WB_MMAP together are rejected with EINVAL.
On non-coherent platforms userspace owns the CPU cache maintenance around GPU access to these buffers. Signed-off-by: Sami Tolvanen <[email protected]> [ Split the BO_CREATE validation and add the WB_MMAP flag checks from the original. - Alvin ] Co-developed-by: Alvin Sun <[email protected]> Signed-off-by: Alvin Sun <[email protected]> --- drivers/gpu/drm/tyr/file.rs | 25 +++++++++++++++++++------ drivers/gpu/drm/tyr/gem.rs | 18 +++++++++++------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/tyr/file.rs b/drivers/gpu/drm/tyr/file.rs index 526eb1d53de42..9ed16c5a8099a 100644 --- a/drivers/gpu/drm/tyr/file.rs +++ b/drivers/gpu/drm/tyr/file.rs @@ -256,19 +256,32 @@ pub(crate) fn bo_create( bocreate: &mut uapi::drm_panthor_bo_create, file: &TyrDrmFile, ) -> Result<u32> { - if bocreate.size == 0 - || bocreate.pad != 0 - || bocreate.flags & !uapi::drm_panthor_bo_flags_DRM_PANTHOR_BO_NO_MMAP != 0 - { + if bocreate.size == 0 || bocreate.pad != 0 { dev_err!( ddev.as_ref(), - "Invalid BO_CREATE params: size={}, pad={}, flags={:#x}\n", + "Invalid BO_CREATE params: size={}, pad={}\n", bocreate.size, - bocreate.pad, + bocreate.pad + ); + return Err(EINVAL); + } + + let no_mmap = uapi::drm_panthor_bo_flags_DRM_PANTHOR_BO_NO_MMAP; + let wb_mmap = uapi::drm_panthor_bo_flags_DRM_PANTHOR_BO_WB_MMAP; + let valid_flags = no_mmap | wb_mmap; + + if bocreate.flags & !valid_flags != 0 { + dev_err!( + ddev.as_ref(), + "Invalid BO_CREATE flags: {:#x}\n", bocreate.flags ); return Err(EINVAL); } + if bocreate.flags & no_mmap != 0 && bocreate.flags & wb_mmap != 0 { + dev_err!(ddev.as_ref(), "BO_CREATE: NO_MMAP conflicts with WB_MMAP\n"); + return Err(EINVAL); + } if bocreate.exclusive_vm_id != 0 { dev_err!(ddev.as_ref(), "BO_CREATE: exclusive_vm_id not supported\n"); diff --git a/drivers/gpu/drm/tyr/gem.rs b/drivers/gpu/drm/tyr/gem.rs index 95e5537e7174b..21b59690d1fc1 100644 --- a/drivers/gpu/drm/tyr/gem.rs +++ b/drivers/gpu/drm/tyr/gem.rs @@ -17,7 +17,8 @@ sync::{ aref::ARef, Arc, // - }, // + }, + uapi, // }; use crate::{ @@ -63,13 +64,16 @@ fn new(_dev: &TyrDrmDevice, _size: usize, args: BoCreateArgs) -> impl PinInit<Se /// Type alias for Tyr GEM buffer objects. pub(crate) type Bo = gem::shmem::Object<BoData>; -/// Returns whether a BO should be mapped write-combine given the device's -/// DMA coherence. -pub(crate) fn should_map_wc(coherent: bool) -> bool { +/// Returns whether a BO should be mapped write-combine. +pub(crate) fn should_map_wc(coherent: bool, flags: u32) -> bool { if coherent { return false; } + if flags & uapi::drm_panthor_bo_flags_DRM_PANTHOR_BO_WB_MMAP != 0 { + return false; + } + true } @@ -86,7 +90,7 @@ pub(crate) fn new_object( let aligned_size = size.checked_next_multiple_of(PAGE_SIZE).ok_or(EINVAL)?; - let map_wc = should_map_wc(coherent); + let map_wc = should_map_wc(coherent, flags); let bo = Bo::new( ddev, aligned_size, @@ -118,7 +122,7 @@ pub(crate) fn new_dummy_object(ddev: &TyrDrmDevice, coherent: bool) -> Result<AR ddev, 4096, shmem::ObjectConfig { - map_wc: should_map_wc(coherent), + map_wc: should_map_wc(coherent, 0), parent_resv_obj: None, }, BoCreateArgs { flags: 0 }, @@ -176,7 +180,7 @@ pub(crate) fn new( ddev, bo_size, shmem::ObjectConfig { - map_wc: should_map_wc(coherent), + map_wc: should_map_wc(coherent, 0), parent_resv_obj: None, }, BoCreateArgs { flags: 0 }, -- 2.43.0
