[Openpvrsgx-devgroup] [PATCH v2] pvrsrv: 1.17: pvr_linux_fence: Repace dma_resv_list by iterator

Anthoine Bourgeois anthoine.bourgeois at gmail.com
Mon Sep 5 20:37:42 CEST 2022


Since 5.19, dma_resv_list is private and the API enforce use of iterators
instead.

v2:
- Remove locks, dma_resv are already locked
- Add dma_resv_reserve_fences before adding a fence

Fixes: 0980db52e9e4 ("FIXME: pvrsrv: 1.17: pvr_linux_fence: there is no direct access to struct dma_resv_list and no resv->seq mechanism any more")
Signed-off-by: Anthoine Bourgeois <anthoine.bourgeois at gmail.com>
---
 .../srvkm/env/linux/pvr_linux_fence.c         | 220 +++++++++++++++++-
 1 file changed, 214 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/srvkm/env/linux/pvr_linux_fence.c b/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/srvkm/env/linux/pvr_linux_fence.c
index bedce47b6b79..fa9762301e89 100644
--- a/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/srvkm/env/linux/pvr_linux_fence.c
+++ b/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/srvkm/env/linux/pvr_linux_fence.c
@@ -538,8 +538,95 @@ static int update_dma_resv_fences_dst(struct pvr_fence_frame *pvr_fence_frame,
 	dma_resv_add_excl_fence(resv, fence_to_signal);
 	return update_reservation_return_value(ret, false);
 #else // (LINUX_VERSION_CODE < KERNEL_VERSION(5,19,0))
-#warning FIXME like in 548e7432dc2da475a18077b612e8d55b8ff51891
-	return -EINVAL;
+	struct dma_fence *fence_to_signal;
+	unsigned blocking_fence_count;
+	int ret;
+
+	struct dma_resv_iter cursor;
+	struct dma_fence *fence;
+
+
+	ret = dma_resv_reserve_fences(resv, 1);
+	if (ret)
+	{
+		return ret;
+	}
+
+	fence_to_signal = create_fence_to_signal(pvr_fence_frame);
+	if (!fence_to_signal)
+	{
+		return -ENOMEM;
+	}
+
+	if (!pvr_fence_frame->have_blocking_fences)
+	{
+		dma_resv_add_fence(resv, fence_to_signal, DMA_RESV_USAGE_WRITE);
+		return 0;
+	}
+
+	dma_resv_for_each_fence(&cursor, resv, DMA_RESV_USAGE_READ, fence) {
+		if (dma_resv_iter_usage(&cursor) == DMA_RESV_USAGE_READ)
+			break;
+
+		if (is_blocking_fence(fence, pvr_fence_frame))
+		{
+			if (allocate_blocking_fence_storage(pvr_fence_frame, 1))
+			{
+				ret = install_and_get_blocking_fence(pvr_fence_frame, 0, fence);
+			}
+			else
+			{
+				dma_fence_put(fence_to_signal);
+				return -ENOMEM;
+			}
+		}
+		else
+		{
+			ret = 1;
+		}
+
+		dma_resv_add_fence(resv, fence_to_signal, DMA_RESV_USAGE_WRITE);
+		return update_reservation_return_value(ret, true);
+	}
+
+	dma_resv_for_each_fence(&cursor, resv, DMA_RESV_USAGE_READ, fence) {
+		if (dma_resv_iter_usage(&cursor) < DMA_RESV_USAGE_READ)
+			continue;
+
+		if (is_blocking_fence(fence, pvr_fence_frame))
+		{
+			blocking_fence_count++;
+		}
+	}
+
+	ret = 1;
+	if (blocking_fence_count)
+	{
+		if (allocate_blocking_fence_storage(pvr_fence_frame, blocking_fence_count))
+		{
+			dma_resv_for_each_fence(&cursor, resv, DMA_RESV_USAGE_READ, fence) {
+				if (dma_resv_iter_usage(&cursor) < DMA_RESV_USAGE_READ)
+					continue;
+
+				if (is_blocking_fence(fence, pvr_fence_frame))
+				{
+					if (!install_and_get_blocking_fence(pvr_fence_frame, cursor.index, fence))
+					{
+						ret = 0;
+					}
+				}
+			}
+		}
+		else
+		{
+			dma_fence_put(fence_to_signal);
+			return -ENOMEM;
+		}
+	}
+
+	dma_resv_add_fence(resv, fence_to_signal, DMA_RESV_USAGE_WRITE);
+
+	return update_reservation_return_value(ret, false);
 #endif
 }
 
@@ -671,8 +758,90 @@ static int update_dma_resv_fences_src(struct pvr_fence_frame *pvr_fence_frame,
 
 	return update_reservation_return_value(ret, !shared_fence_count);
 #else // (LINUX_VERSION_CODE < KERNEL_VERSION(5,19,0))
-#warning FIXME like in 548e7432dc2da475a18077b612e8d55b8ff51891
-	return -EINVAL;
+	struct dma_resv_iter cursor;
+	struct dma_fence *fence;
+	struct dma_fence *fence_to_signal = NULL;
+	struct dma_fence *blocking_fence = NULL;
+	bool reserve = true;
+	unsigned shared_fence_count;
+	int ret;
+
+	if (!pvr_fence_frame->have_blocking_fences)
+	{
+		ret = dma_resv_reserve_fences(resv, 1);
+		if (ret)
+		{
+			return ret;
+		}
+
+		fence_to_signal = create_fence_to_signal(pvr_fence_frame);
+		if (!fence_to_signal)
+		{
+			return -ENOMEM;
+		}
+
+		dma_resv_add_fence(resv, fence_to_signal, DMA_RESV_USAGE_READ);
+
+		return 0;
+	}
+
+	shared_fence_count = 0;
+	dma_resv_for_each_fence(&cursor, resv, DMA_RESV_USAGE_READ, fence) {
+		if (dma_resv_iter_usage(&cursor) <= DMA_RESV_USAGE_WRITE)
+			continue;
+
+		shared_fence_count++;
+
+		if (is_pvr_fence(fence))
+		{
+			reserve = false;
+
+			if (is_blocking_fence(fence, pvr_fence_frame))
+			{
+				blocking_fence = fence;
+			}
+			break;
+		}
+	}
+
+	if (reserve)
+	{
+		ret = dma_resv_reserve_fences(resv, 1);
+		if (ret)
+		{
+			return ret;
+		}
+	}
+
+	fence_to_signal = create_fence_to_signal(pvr_fence_frame);
+	if (!fence_to_signal)
+	{
+		return -ENOMEM;
+	}
+
+	ret = 1;
+	if (!blocking_fence && !shared_fence_count)
+	{
+		dma_resv_for_each_fence(&cursor, resv, DMA_RESV_USAGE_WRITE, fence) {
+			if (is_blocking_fence(fence, pvr_fence_frame))
+			{
+				if (allocate_blocking_fence_storage(pvr_fence_frame, 1))
+				{
+					ret = install_and_get_blocking_fence(pvr_fence_frame, 0, fence);
+				}
+				else
+				{
+					dma_fence_put(fence_to_signal);
+					return -ENOMEM;
+				}
+				break;
+			}
+		}
+	}
+
+	dma_resv_add_fence(resv, fence_to_signal, DMA_RESV_USAGE_READ);
+
+	return update_reservation_return_value(ret, !shared_fence_count);
 #endif
 }
 
@@ -1090,8 +1259,47 @@ static bool resv_is_blocking(struct dma_resv *resv,
 	rcu_read_unlock();
 	goto retry;
 #else
-	// FIXME: there is no resv-seq any more since 8f94eda39952a8c7323bad2bf752bdfe78101b20
-	return true;
+	struct dma_resv_iter cursor;
+	struct dma_fence *fence;
+	bool blocking;
+
+	blocking = false;
+
+	rcu_read_lock();
+
+	if (is_dst)
+	{
+		dma_resv_iter_begin(&cursor, resv, DMA_RESV_USAGE_READ);
+		dma_resv_for_each_fence_unlocked(&cursor, fence) {
+			if (dma_resv_iter_usage(&cursor) <= DMA_RESV_USAGE_WRITE)
+				continue;
+
+			blocking = fence_is_blocking(fence, psSyncInfo);
+			if (blocking)
+				break;
+		}
+		dma_resv_iter_end(&cursor);
+	}
+
+	if (!blocking)
+	{
+		dma_resv_iter_begin(&cursor, resv, DMA_RESV_USAGE_READ);
+		dma_resv_for_each_fence_unlocked(&cursor, fence) {
+			if (dma_resv_iter_usage(&cursor) == DMA_RESV_USAGE_READ) {
+				break;
+			}
+
+			if (fence_is_blocking(fence, psSyncInfo)) {
+				blocking = true;
+				break;
+			}
+		}
+		dma_resv_iter_end(&cursor);
+	}
+
+	rcu_read_unlock();
+
+	return blocking;
 #endif
 }
 
-- 
2.35.1



More information about the openpvrsgx-devgroup mailing list