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

drm/msm: Add wait-boost support

Add a way for various userspace waits to signal urgency.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Patchwork: https://patchwork.freedesktop.org/patch/525817/
Link: https://lore.kernel.org/r/20230308155322.344664-14-robdclark@gmail.com

+25 -6
+8 -4
drivers/gpu/drm/msm/msm_drv.c
··· 46 46 * - 1.8.0 - Add MSM_BO_CACHED_COHERENT for supported GPUs (a6xx) 47 47 * - 1.9.0 - Add MSM_SUBMIT_FENCE_SN_IN 48 48 * - 1.10.0 - Add MSM_SUBMIT_BO_NO_IMPLICIT 49 + * - 1.11.0 - Add wait boost (MSM_WAIT_FENCE_BOOST, MSM_PREP_BOOST) 49 50 */ 50 51 #define MSM_VERSION_MAJOR 1 51 52 #define MSM_VERSION_MINOR 10 ··· 900 899 } 901 900 902 901 static int wait_fence(struct msm_gpu_submitqueue *queue, uint32_t fence_id, 903 - ktime_t timeout) 902 + ktime_t timeout, uint32_t flags) 904 903 { 905 904 struct dma_fence *fence; 906 905 int ret; ··· 928 927 if (!fence) 929 928 return 0; 930 929 930 + if (flags & MSM_WAIT_FENCE_BOOST) 931 + dma_fence_set_deadline(fence, ktime_get()); 932 + 931 933 ret = dma_fence_wait_timeout(fence, true, timeout_to_jiffies(&timeout)); 932 934 if (ret == 0) { 933 935 ret = -ETIMEDOUT; ··· 951 947 struct msm_gpu_submitqueue *queue; 952 948 int ret; 953 949 954 - if (args->pad) { 955 - DRM_ERROR("invalid pad: %08x\n", args->pad); 950 + if (args->flags & ~MSM_WAIT_FENCE_FLAGS) { 951 + DRM_ERROR("invalid flags: %08x\n", args->flags); 956 952 return -EINVAL; 957 953 } 958 954 ··· 963 959 if (!queue) 964 960 return -ENOENT; 965 961 966 - ret = wait_fence(queue, args->fence, to_ktime(args->timeout)); 962 + ret = wait_fence(queue, args->fence, to_ktime(args->timeout), args->flags); 967 963 968 964 msm_submitqueue_put(queue); 969 965
+5
drivers/gpu/drm/msm/msm_gem.c
··· 895 895 op & MSM_PREP_NOSYNC ? 0 : timeout_to_jiffies(timeout); 896 896 long ret; 897 897 898 + if (op & MSM_PREP_BOOST) { 899 + dma_resv_set_deadline(obj->resv, dma_resv_usage_rw(write), 900 + ktime_get()); 901 + } 902 + 898 903 ret = dma_resv_wait_timeout(obj->resv, dma_resv_usage_rw(write), 899 904 true, remain); 900 905 if (ret == 0)
+12 -2
include/uapi/drm/msm_drm.h
··· 151 151 #define MSM_PREP_READ 0x01 152 152 #define MSM_PREP_WRITE 0x02 153 153 #define MSM_PREP_NOSYNC 0x04 154 + #define MSM_PREP_BOOST 0x08 154 155 155 - #define MSM_PREP_FLAGS (MSM_PREP_READ | MSM_PREP_WRITE | MSM_PREP_NOSYNC) 156 + #define MSM_PREP_FLAGS (MSM_PREP_READ | \ 157 + MSM_PREP_WRITE | \ 158 + MSM_PREP_NOSYNC | \ 159 + MSM_PREP_BOOST | \ 160 + 0) 156 161 157 162 struct drm_msm_gem_cpu_prep { 158 163 __u32 handle; /* in */ ··· 291 286 292 287 }; 293 288 289 + #define MSM_WAIT_FENCE_BOOST 0x00000001 290 + #define MSM_WAIT_FENCE_FLAGS ( \ 291 + MSM_WAIT_FENCE_BOOST | \ 292 + 0) 293 + 294 294 /* The normal way to synchronize with the GPU is just to CPU_PREP on 295 295 * a buffer if you need to access it from the CPU (other cmdstream 296 296 * submission from same or other contexts, PAGE_FLIP ioctl, etc, all ··· 305 295 */ 306 296 struct drm_msm_wait_fence { 307 297 __u32 fence; /* in */ 308 - __u32 pad; 298 + __u32 flags; /* in, bitmask of MSM_WAIT_FENCE_x */ 309 299 struct drm_msm_timespec timeout; /* in */ 310 300 __u32 queueid; /* in, submitqueue id */ 311 301 };