[PATCH] drm/amdgpu: only keep most recent fence for each context

Arvind Yadav Arvind.Yadav at amd.com
Tue Apr 15 14:18:48 UTC 2025


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.deucher at amd.com>
Cc: Christian König <christian.koenig at amd.com>
Cc: Sunil Khatri <sunil.khatri at amd.com>
Cc: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam at amd.com>
Signed-off-by: Arvind Yadav <arvind.yadav at 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



More information about the amd-gfx mailing list