[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