Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/panfrost: Add flag to map GEM object Write-Back Cacheable

Will be used by the UMD to optimize CPU accesses to buffers
that are frequently read by the CPU, or on which the access
pattern makes non-cacheable mappings inefficient.

Mapping buffers CPU-cached implies taking care of the CPU
cache maintenance in the UMD, unless the GPU is IO coherent.

v2:
- Add more to the commit message

v3:
- No changes

v4:
- Fix the map_wc test in panfrost_ioctl_query_bo_info()

v5:
- Drop Steve's R-b (enough has changed to justify a new review)

v6:
- Collect R-b

v7:
- No changes

v8:
- Fix double drm_gem_object_funcs::export assignment

Signed-off-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Link: https://patch.msgid.link/20251208100841.730527-13-boris.brezillon@collabora.com
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>

authored by

Faith Ekstrand and committed by
Boris Brezillon
62eedf1c d17592e6

+49 -3
+8 -2
drivers/gpu/drm/panfrost/panfrost_drv.c
··· 126 126 return 0; 127 127 } 128 128 129 + #define PANFROST_BO_FLAGS (PANFROST_BO_NOEXEC | \ 130 + PANFROST_BO_HEAP | \ 131 + PANFROST_BO_WB_MMAP) 132 + 129 133 static int panfrost_ioctl_create_bo(struct drm_device *dev, void *data, 130 134 struct drm_file *file) 131 135 { ··· 139 135 struct panfrost_gem_mapping *mapping; 140 136 int ret; 141 137 142 - if (!args->size || args->pad || 143 - (args->flags & ~(PANFROST_BO_NOEXEC | PANFROST_BO_HEAP))) 138 + if (!args->size || args->pad || (args->flags & ~PANFROST_BO_FLAGS)) 144 139 return -EINVAL; 145 140 146 141 /* Heaps should never be executable */ ··· 659 656 660 657 if (bo->is_heap) 661 658 args->create_flags |= PANFROST_BO_HEAP; 659 + 660 + if (!bo->base.map_wc) 661 + args->create_flags |= PANFROST_BO_WB_MMAP; 662 662 } 663 663 664 664 drm_gem_object_put(gem_obj);
+32
drivers/gpu/drm/panfrost/panfrost_gem.c
··· 444 444 return &obj->base.base; 445 445 } 446 446 447 + static bool 448 + should_map_wc(struct panfrost_gem_object *bo) 449 + { 450 + struct panfrost_device *pfdev = to_panfrost_device(bo->base.base.dev); 451 + 452 + /* We can't do uncached mappings if the device is coherent, 453 + * because the zeroing done by the shmem layer at page allocation 454 + * time happens on a cached mapping which isn't CPU-flushed (at least 455 + * not on Arm64 where the flush is deferred to PTE setup time, and 456 + * only done conditionally based on the mapping permissions). We can't 457 + * rely on dma_map_sgtable()/dma_sync_sgtable_for_xxx() either to flush 458 + * those, because they are NOPed if dma_dev_coherent() returns true. 459 + */ 460 + if (pfdev->coherent) 461 + return false; 462 + 463 + /* Cached mappings are explicitly requested, so no write-combine. */ 464 + if (bo->wb_mmap) 465 + return false; 466 + 467 + /* The default is write-combine. */ 468 + return true; 469 + } 470 + 447 471 struct panfrost_gem_object * 448 472 panfrost_gem_create(struct drm_device *dev, size_t size, u32 flags) 449 473 { 450 474 struct drm_gem_shmem_object *shmem; 451 475 struct panfrost_gem_object *bo; 476 + 477 + /* The heap buffer is not supposed to be CPU-visible, so don't allow 478 + * WB_MMAP on those. 479 + */ 480 + if ((flags & PANFROST_BO_HEAP) && (flags & PANFROST_BO_WB_MMAP)) 481 + return ERR_PTR(-EINVAL); 452 482 453 483 /* Round up heap allocations to 2MB to keep fault handling simple */ 454 484 if (flags & PANFROST_BO_HEAP) ··· 491 461 bo = to_panfrost_bo(&shmem->base); 492 462 bo->noexec = !!(flags & PANFROST_BO_NOEXEC); 493 463 bo->is_heap = !!(flags & PANFROST_BO_HEAP); 464 + bo->wb_mmap = !!(flags & PANFROST_BO_WB_MMAP); 465 + bo->base.map_wc = should_map_wc(bo); 494 466 495 467 return bo; 496 468 }
+5
drivers/gpu/drm/panfrost/panfrost_gem.h
··· 98 98 bool noexec :1; 99 99 bool is_heap :1; 100 100 101 + /* On coherent devices, this reflects the creation flags, not the true 102 + * cacheability attribute of the mapping. 103 + */ 104 + bool wb_mmap :1; 105 + 101 106 #ifdef CONFIG_DEBUG_FS 102 107 struct panfrost_gem_debugfs debugfs; 103 108 #endif
+4 -1
include/uapi/drm/panfrost_drm.h
··· 124 124 __s64 timeout_ns; 125 125 }; 126 126 127 - /* Valid flags to pass to drm_panfrost_create_bo */ 127 + /* Valid flags to pass to drm_panfrost_create_bo. 128 + * PANFROST_BO_WB_MMAP can't be set if PANFROST_BO_HEAP is. 129 + */ 128 130 #define PANFROST_BO_NOEXEC 1 129 131 #define PANFROST_BO_HEAP 2 132 + #define PANFROST_BO_WB_MMAP 4 130 133 131 134 /** 132 135 * struct drm_panfrost_create_bo - ioctl argument for creating Panfrost BOs.