diff options
Diffstat (limited to 'meta-amdfalconx86/recipes-kernel/linux/files/1121-add-the-interface-of-waiting-multiple-fences-v2.patch')
-rw-r--r-- | meta-amdfalconx86/recipes-kernel/linux/files/1121-add-the-interface-of-waiting-multiple-fences-v2.patch | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/meta-amdfalconx86/recipes-kernel/linux/files/1121-add-the-interface-of-waiting-multiple-fences-v2.patch b/meta-amdfalconx86/recipes-kernel/linux/files/1121-add-the-interface-of-waiting-multiple-fences-v2.patch new file mode 100644 index 00000000..1502ec44 --- /dev/null +++ b/meta-amdfalconx86/recipes-kernel/linux/files/1121-add-the-interface-of-waiting-multiple-fences-v2.patch @@ -0,0 +1,281 @@ +From 5f2af20ad85a19ddbdd1ea7b63b0f21ac499ed88 Mon Sep 17 00:00:00 2001 +From: Sanjay R Mehta <sanju.mehta@amd.com> +Date: Mon, 19 Sep 2016 12:31:46 +0530 +Subject: [PATCH 11/12] 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> +Signed-off-by: Sanjay R Mehta <sanju.mehta@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 + + drivers/gpu/drm/amd/include/uapi/drm/amdgpu_drm.h | 27 ++++ + 4 files changed, 201 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +index 28f8481..b15b3b5 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -1861,6 +1861,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 f983846..0d1346c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +@@ -1021,6 +1021,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 b6de8d5..3ce4ee3 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +@@ -749,6 +749,7 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { + DRM_IOCTL_DEF_DRV(AMDGPU_CS, amdgpu_cs_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(AMDGPU_INFO, amdgpu_info_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(AMDGPU_WAIT_CS, amdgpu_cs_wait_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), ++ DRM_IOCTL_DEF_DRV(AMDGPU_WAIT_FENCES, amdgpu_cs_wait_fences_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(AMDGPU_GEM_METADATA, amdgpu_gem_metadata_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(AMDGPU_GEM_VA, amdgpu_gem_va_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(AMDGPU_GEM_OP, amdgpu_gem_op_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), +diff --git a/drivers/gpu/drm/amd/include/uapi/drm/amdgpu_drm.h b/drivers/gpu/drm/amd/include/uapi/drm/amdgpu_drm.h +index 17c7d3f..8ff615b 100644 +--- a/drivers/gpu/drm/amd/include/uapi/drm/amdgpu_drm.h ++++ b/drivers/gpu/drm/amd/include/uapi/drm/amdgpu_drm.h +@@ -46,6 +46,7 @@ + #define DRM_AMDGPU_WAIT_CS 0x09 + #define DRM_AMDGPU_GEM_OP 0x10 + #define DRM_AMDGPU_GEM_USERPTR 0x11 ++#define DRM_AMDGPU_WAIT_FENCES 0x12 + #define DRM_AMDGPU_FREESYNC 0x14 + + #define DRM_IOCTL_AMDGPU_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create) +@@ -60,6 +61,7 @@ + #define DRM_IOCTL_AMDGPU_WAIT_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_CS, union drm_amdgpu_wait_cs) + #define DRM_IOCTL_AMDGPU_GEM_OP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_OP, struct drm_amdgpu_gem_op) + #define DRM_IOCTL_AMDGPU_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_USERPTR, struct drm_amdgpu_gem_userptr) ++#define DRM_IOCTL_AMDGPU_WAIT_FENCES DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_FENCES, union drm_amdgpu_wait_fences) + #define DRM_IOCTL_AMDGPU_FREESYNC DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_FREESYNC, struct drm_amdgpu_freesync) + + #define AMDGPU_GEM_DOMAIN_CPU 0x1 +@@ -301,6 +303,31 @@ union drm_amdgpu_wait_cs { + struct drm_amdgpu_wait_cs_out out; + }; + ++struct drm_amdgpu_fence { ++ uint32_t ctx_id; ++ uint32_t ip_type; ++ uint32_t ip_instance; ++ uint32_t ring; ++ uint64_t seq_no; ++}; ++ ++struct drm_amdgpu_wait_fences_in { ++ /** This points to uint64_t * which points to fences */ ++ uint64_t fences; ++ uint32_t fence_count; ++ uint32_t wait_all; ++ uint64_t timeout_ns; ++}; ++ ++struct drm_amdgpu_wait_fences_out { ++ uint64_t status; ++}; ++ ++union drm_amdgpu_wait_fences { ++ struct drm_amdgpu_wait_fences_in in; ++ struct drm_amdgpu_wait_fences_out out; ++}; ++ + #define AMDGPU_GEM_OP_GET_GEM_CREATE_INFO 0 + #define AMDGPU_GEM_OP_SET_PLACEMENT 1 + +-- +2.7.4 + |