[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