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

H. Nikolaus Schaller hns at goldelico.com
Thu Sep 8 09:37:58 CEST 2022


Hi Anthoine,
no problem with delay... Progress of this project is slow like a snail :)

I have reverted v1 and merged this one. So with the next major update it will be part of the openpvrsgx tree.

BR and thanks,
Nikolaus


> Am 05.09.2022 um 20:48 schrieb Anthoine Bourgeois <anthoine.bourgeois at gmail.com>:
> 
> 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