Mesa passes shared bo, fence syncobj to userq_ioctl. There can be duplicates here or some fences that are old. This patch is remove duplicates fence and only keep the most recent fence for each context.
Cc: Alex Deucher <alexander.deuc...@amd.com> Cc: Christian König <christian.koe...@amd.com> Cc: Sunil Khatri <sunil.kha...@amd.com> Cc: Arunpravin Paneer Selvam <arunpravin.paneersel...@amd.com> Signed-off-by: Arvind Yadav <arvind.ya...@amd.com> --- .../gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c index a4953d668972..9a09d545ceb5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c @@ -25,6 +25,7 @@ #include <linux/kref.h> #include <linux/slab.h> #include <linux/dma-fence-unwrap.h> +#include <linux/sort.h> #include <drm/drm_exec.h> #include <drm/drm_syncobj.h> @@ -584,6 +585,24 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, #endif #ifdef CONFIG_DRM_AMDGPU_NAVI3X_USERQ +static int fence_cmp(const void *_a, const void *_b) +{ + struct dma_fence *a = *(struct dma_fence **)_a; + struct dma_fence *b = *(struct dma_fence **)_b; + + if (a->context < b->context) + return -1; + else if (a->context > b->context) + return 1; + + if (dma_fence_is_later(b, a)) + return 1; + else if (dma_fence_is_later(a, b)) + return -1; + + return 0; +} + int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { @@ -840,6 +859,24 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, fences[num_fences++] = fence; } + if (num_fences > 1) { + int j = 0; + + sort(fences, num_fences, sizeof(*fences), fence_cmp, NULL); + + /* + * Only keep the most recent fence for each context. + */ + for (int i = 1; i < num_fences; i++) { + if (fences[i]->context == fences[j]->context) + dma_fence_put(fences[i]); + else + fences[++j] = fences[i]; + } + + num_fences = ++j; + } + for (i = 0, cnt = 0; i < num_fences; i++) { struct amdgpu_userq_fence_driver *fence_drv; struct amdgpu_userq_fence *userq_fence; -- 2.34.1