[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:48:08 CEST 2022


Hello,

Sorry for the delay. I take some time to fix the dma_resv patch and sent
a v2 tested on wlroots examples.

BR,
Anthoine

On Mon, Sep 05, 2022 at 08:37:42PM +0200, Anthoine Bourgeois wrote:
>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