diff options
Diffstat (limited to 'meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0749-drm-amdgpu-add-the-interface-of-waiting-multiple-fen.patch')
-rw-r--r-- | meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0749-drm-amdgpu-add-the-interface-of-waiting-multiple-fen.patch | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0749-drm-amdgpu-add-the-interface-of-waiting-multiple-fen.patch b/meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0749-drm-amdgpu-add-the-interface-of-waiting-multiple-fen.patch new file mode 100644 index 00000000..c6224dcf --- /dev/null +++ b/meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0749-drm-amdgpu-add-the-interface-of-waiting-multiple-fen.patch @@ -0,0 +1,228 @@ +From a55936889bece9813b14815182e3452c4643614a Mon Sep 17 00:00:00 2001 +From: Junwei Zhang <Jerry.Zhang@amd.com> +Date: Thu, 20 Aug 2015 13:06:57 +0800 +Subject: [PATCH 0749/1050] drm/amdgpu: add the interface of waiting multiple + fences (v2) + +v2: agd: rebase and squash in all the previous optimizations and +changes so everything compiles. + +Signed-off-by: Junwei Zhang <Jerry.Zhang@amd.com> +Reviewed-by: Monk Liu <monk.liu@amd.com> +Reviewed-by: Jammy Zhou <Jammy.Zhou@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 + + drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 171 ++++++++++++++++++++++++++++++++ + drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 1 + + 3 files changed, 174 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +index 8822ba1..afc76d4 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -1803,6 +1803,8 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp); + int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); + int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); ++int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *filp); + + int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +index 6096eff..cb201be 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +@@ -957,6 +957,177 @@ int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, + } + + /** ++ * amdgpu_cs_get_fence - helper to get fence from drm_amdgpu_fence ++ * ++ * @adev: amdgpu device ++ * @filp: file private ++ * @user: drm_amdgpu_fence copied from user space ++ */ ++static struct fence *amdgpu_cs_get_fence(struct amdgpu_device *adev, ++ struct drm_file *filp, ++ struct drm_amdgpu_fence *user) ++{ ++ struct amdgpu_ring *ring; ++ struct amdgpu_ctx *ctx; ++ struct fence *fence; ++ int r; ++ ++ r = amdgpu_cs_get_ring(adev, user->ip_type, user->ip_instance, ++ user->ring, &ring); ++ if (r) ++ return ERR_PTR(r); ++ ++ ctx = amdgpu_ctx_get(filp->driver_priv, user->ctx_id); ++ if (ctx == NULL) ++ return ERR_PTR(-EINVAL); ++ ++ fence = amdgpu_ctx_get_fence(ctx, ring, user->seq_no); ++ amdgpu_ctx_put(ctx); ++ ++ return fence; ++} ++ ++/** ++ * amdgpu_cs_wait_all_fence - wait on all fences to signal ++ * ++ * @adev: amdgpu device ++ * @filp: file private ++ * @wait: wait parameters ++ * @fences: array of drm_amdgpu_fence ++ */ ++static int amdgpu_cs_wait_all_fences(struct amdgpu_device *adev, ++ struct drm_file *filp, ++ union drm_amdgpu_wait_fences *wait, ++ struct drm_amdgpu_fence *fences) ++{ ++ uint32_t fence_count = wait->in.fence_count; ++ unsigned i; ++ long r = 1; ++ ++ for (i = 0; i < fence_count; i++) { ++ struct fence *fence; ++ unsigned long timeout = amdgpu_gem_timeout(wait->in.timeout_ns); ++ ++ fence = amdgpu_cs_get_fence(adev, filp, &fences[i]); ++ if (IS_ERR(fence)) ++ return PTR_ERR(fence); ++ else if (!fence) ++ continue; ++ ++ r = fence_wait_timeout(fence, true, timeout); ++ if (r < 0) ++ return r; ++ ++ if (r == 0) ++ break; ++ } ++ ++ memset(wait, 0, sizeof(*wait)); ++ wait->out.status = (r > 0); ++ ++ return 0; ++} ++ ++/** ++ * amdgpu_cs_wait_any_fence - wait on any fence to signal ++ * ++ * @adev: amdgpu device ++ * @filp: file private ++ * @wait: wait parameters ++ * @fences: array of drm_amdgpu_fence ++ */ ++static int amdgpu_cs_wait_any_fence(struct amdgpu_device *adev, ++ struct drm_file *filp, ++ union drm_amdgpu_wait_fences *wait, ++ struct drm_amdgpu_fence *fences) ++{ ++ unsigned long timeout = amdgpu_gem_timeout(wait->in.timeout_ns); ++ uint32_t fence_count = wait->in.fence_count; ++ struct fence **array; ++ unsigned i; ++ long r; ++ ++ /* Prepare the fence array */ ++ array = (struct fence **)kcalloc(fence_count, sizeof(struct fence *), ++ GFP_KERNEL); ++ if (array == NULL) ++ return -ENOMEM; ++ ++ for (i = 0; i < fence_count; i++) { ++ struct fence *fence; ++ ++ fence = amdgpu_cs_get_fence(adev, filp, &fences[i]); ++ if (IS_ERR(fence)) { ++ r = PTR_ERR(fence); ++ goto err_free_fence_array; ++ } else if (fence) { ++ array[i] = fence; ++ } else { /* NULL, the fence has been already signaled */ ++ r = 1; ++ goto out; ++ } ++ } ++ ++ r = fence_wait_any_timeout(array, fence_count, true, timeout); ++ if (r < 0) ++ goto err_free_fence_array; ++ ++out: ++ memset(wait, 0, sizeof(*wait)); ++ wait->out.status = (r > 0); ++ /* set return value 0 to indicate success */ ++ r = 0; ++ ++err_free_fence_array: ++ for (i = 0; i < fence_count; i++) ++ fence_put(array[i]); ++ kfree(array); ++ ++ return r; ++} ++ ++/** ++ * amdgpu_cs_wait_fences_ioctl - wait for multiple command submissions to finish ++ * ++ * @dev: drm device ++ * @data: data from userspace ++ * @filp: file private ++ */ ++int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *filp) ++{ ++ struct amdgpu_device *adev = dev->dev_private; ++ union drm_amdgpu_wait_fences *wait = data; ++ uint32_t fence_count = wait->in.fence_count; ++ struct drm_amdgpu_fence *fences_user; ++ struct drm_amdgpu_fence *fences; ++ int r; ++ ++ /* Get the fences from userspace */ ++ fences = kmalloc_array(fence_count, sizeof(struct drm_amdgpu_fence), ++ GFP_KERNEL); ++ if (fences == NULL) ++ return -ENOMEM; ++ ++ fences_user = (void __user *)wait->in.fences; ++ if (copy_from_user(fences, fences_user, ++ sizeof(struct drm_amdgpu_fence) * fence_count)) { ++ r = -EFAULT; ++ goto err_free_fences; ++ } ++ ++ if (wait->in.wait_all) ++ r = amdgpu_cs_wait_all_fences(adev, filp, wait, fences); ++ else ++ r = amdgpu_cs_wait_any_fence(adev, filp, wait, fences); ++ ++err_free_fences: ++ kfree(fences); ++ ++ return r; ++} ++ ++/** + * amdgpu_cs_find_bo_va - find bo_va for VM address + * + * @parser: command submission parser context +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +index 3c4c595..a571d2b 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +@@ -698,6 +698,7 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { + DRM_IOCTL_DEF_DRV(AMDGPU_CS, amdgpu_cs_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(AMDGPU_INFO, amdgpu_info_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(AMDGPU_WAIT_CS, amdgpu_cs_wait_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), ++ DRM_IOCTL_DEF_DRV(AMDGPU_WAIT_FENCES, amdgpu_cs_wait_fences_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(AMDGPU_GEM_METADATA, amdgpu_gem_metadata_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(AMDGPU_GEM_VA, amdgpu_gem_va_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(AMDGPU_GEM_OP, amdgpu_gem_op_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), +-- +1.9.1 + |