[Openpvrsgx-devgroup] [RFC][PATCH] pvrsrv: 1.17: pvr_linux_fence: Repace dma_resv_list by iterator
H. Nikolaus Schaller
hns at goldelico.com
Mon Jul 4 09:41:51 CEST 2022
Oh great! I have just done a compile test which goes fine.
And I can boot an omap5evm with driver loaded.
But I don't know if that initialization already uses (and tests) DMA.
And unfortunately I have no working 1.17 user-space setup fulfilling
exact library requirements.
Anyone else with a working setup?
BR and thanks,
Nikolaus
> Am 02.07.2022 um 16:09 schrieb Anthoine Bourgeois <anthoine.bourgeois at gmail.com>:
>
> To be tested! I don't have the hardware, this commit is not tested.
>
> Replace all the list loops by iterators changes the code so much it wasn't
> clean to do small macro block so there is one macro block per function.
>
> 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 | 234 +++++++++++++++++-
> 1 file changed, 228 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..3f45860afc46 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,99 @@ 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;
> +
> + dma_resv_lock(resv, NULL);
> +
> + fence_to_signal = create_fence_to_signal(pvr_fence_frame);
> + if (!fence_to_signal)
> + {
> + ret = -ENOMEM;
> + goto unlock;
> + }
> +
> + if (!pvr_fence_frame->have_blocking_fences)
> + {
> + dma_resv_add_fence(resv, fence_to_signal, DMA_RESV_USAGE_WRITE);
> + dma_resv_unlock(resv);
> + 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);
> + ret = -ENOMEM;
> + goto unlock;
> + }
> + }
> + else
> + {
> + ret = 1;
> + }
> +
> + dma_resv_add_fence(resv, fence_to_signal, DMA_RESV_USAGE_WRITE);
> + dma_resv_unlock(resv);
> + 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);
> + ret = -ENOMEM;
> + goto unlock;
> + }
> + }
> +
> + dma_resv_add_fence(resv, fence_to_signal, DMA_RESV_USAGE_WRITE);
> + dma_resv_unlock(resv);
> +
> + return update_reservation_return_value(ret, false);
> +unlock:
> + dma_resv_unlock(resv);
> + return ret;
> #endif
> }
>
> @@ -671,8 +762,100 @@ 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;
> +
> + dma_resv_lock(resv, NULL);
> +
> + if (!pvr_fence_frame->have_blocking_fences)
> + {
> + ret = dma_resv_reserve_fences(resv, 1);
> + if (ret)
> + {
> + goto unlock;
> + }
> +
> + fence_to_signal = create_fence_to_signal(pvr_fence_frame);
> + if (!fence_to_signal)
> + {
> + ret = -ENOMEM;
> + goto unlock;
> + }
> +
> + dma_resv_add_fence(resv, fence_to_signal, DMA_RESV_USAGE_READ);
> +
> + ret = 0;
> + goto unlock;
> + }
> +
> + 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)
> + {
> + goto unlock;
> + }
> + }
> +
> + fence_to_signal = create_fence_to_signal(pvr_fence_frame);
> + if (!fence_to_signal)
> + {
> + ret = -ENOMEM;
> + goto unlock;
> + }
> +
> + 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
> + {
> + ret = -ENOMEM;
> + dma_fence_put(fence_to_signal);
> + goto unlock;
> + }
> + break;
> + }
> + }
> + }
> +
> + dma_resv_add_fence(resv, fence_to_signal, DMA_RESV_USAGE_READ);
> + dma_resv_unlock(resv);
> +
> + return update_reservation_return_value(ret, !shared_fence_count);
> +unlock:
> + dma_resv_lock(resv, NULL);
> + return ret;
> #endif
> }
>
> @@ -1090,8 +1273,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