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

Arvind Yadav Arvind.Yadav at amd.com
Wed Apr 23 10:48:24 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.

v2: Export this code from dma-fence-unwrap.c(by Christian).

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>
---
 drivers/dma-buf/dma-fence-unwrap.c            | 29 +++++++++++++++++++
 .../gpu/drm/amd/amdgpu/amdgpu_userq_fence.c   |  2 ++
 include/linux/dma-fence-unwrap.h              |  3 ++
 3 files changed, 34 insertions(+)

diff --git a/drivers/dma-buf/dma-fence-unwrap.c b/drivers/dma-buf/dma-fence-unwrap.c
index 2a059ac0ed27..18874eedf091 100644
--- a/drivers/dma-buf/dma-fence-unwrap.c
+++ b/drivers/dma-buf/dma-fence-unwrap.c
@@ -179,3 +179,32 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences,
 	return tmp;
 }
 EXPORT_SYMBOL_GPL(__dma_fence_unwrap_merge);
+
+/**
+ * dma_fence_shrink_array - return the shrink fences from fence containers
+ * @fences: array of fence
+ * @num_fences: number of fence in fence array @fences
+ *
+ * only keep most recent fence for each context. It will remove duplicate
+ * and old fence of same context.
+ */
+unsigned short dma_fence_shrink_array(struct dma_fence **fences,
+				      unsigned short num_fences)
+{
+	unsigned short count = 0;
+
+	if (num_fences <= 1)
+		return num_fences;
+
+	sort(fences, num_fences, sizeof(*fences), fence_cmp, NULL);
+
+	for (int i = 1; i < num_fences; i++) {
+		if (fences[i]->context == fences[count]->context)
+			dma_fence_put(fences[i]);
+		else
+			fences[++count] = fences[i];
+	}
+
+	return ++count;
+}
+EXPORT_SYMBOL_GPL(dma_fence_shrink_array);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
index 3288c2ff692e..cc74bb0ed06f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
@@ -851,6 +851,8 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
 			fences[num_fences++] = fence;
 		}
 
+		num_fences = dma_fence_shrink_array(fences, num_fences);
+
 		waitq = idr_find(&userq_mgr->userq_idr, wait_info->waitq_id);
 		if (!waitq)
 			goto free_fences;
diff --git a/include/linux/dma-fence-unwrap.h b/include/linux/dma-fence-unwrap.h
index 66b1e56fbb81..94801feeee4b 100644
--- a/include/linux/dma-fence-unwrap.h
+++ b/include/linux/dma-fence-unwrap.h
@@ -72,4 +72,7 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences,
 		__dma_fence_unwrap_merge(ARRAY_SIZE(__f), __f, __c);	\
 	})
 
+
+unsigned short dma_fence_shrink_array(struct dma_fence **fences,
+				      unsigned short num_fences);
 #endif
-- 
2.34.1



More information about the amd-gfx mailing list