[PATCH 2/7] drm/syncobj: Do not allocate an array to store zeros when waiting

Maíra Canal mcanal at igalia.com
Mon Mar 24 21:55:49 UTC 2025


Hi Tvrtko,

On 18/03/25 12:54, Tvrtko Ursulin wrote:
> When waiting on syncobjs the current code allocates a temporary array only
> to fill it up with all zeros.
> 
> We can avoid that by relying on the allocated entry array already being
> zero allocated.
> 
> For the timeline mode we can fetch the timeline point values as we
> populate the entries array so also do not need this additional temporary
> allocation.
> 
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at igalia.com>

Reviewed-by: Maíra Canal <mcanal at igalia.com>

Best Regards,
- Maíra

> ---
>   drivers/gpu/drm/drm_syncobj.c | 39 ++++++++++++++---------------------
>   1 file changed, 15 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
> index d0d60c331df8..fd5ba6c89666 100644
> --- a/drivers/gpu/drm/drm_syncobj.c
> +++ b/drivers/gpu/drm/drm_syncobj.c
> @@ -1028,7 +1028,7 @@ static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj,
>   }
>   
>   static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
> -						  void __user *user_points,
> +						  u64 __user *user_points,
>   						  uint32_t count,
>   						  uint32_t flags,
>   						  signed long timeout,
> @@ -1036,9 +1036,8 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
>   						  ktime_t *deadline)
>   {
>   	struct syncobj_wait_entry *entries;
> -	struct dma_fence *fence;
> -	uint64_t *points;
>   	uint32_t signaled_count, i;
> +	struct dma_fence *fence;
>   
>   	if (flags & (DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT |
>   		     DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE)) {
> @@ -1046,24 +1045,14 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
>   		lockdep_assert_none_held_once();
>   	}
>   
> -	points = kmalloc_array(count, sizeof(*points), GFP_KERNEL);
> -	if (points == NULL)
> -		return -ENOMEM;
> -
> -	if (!user_points) {
> -		memset(points, 0, count * sizeof(uint64_t));
> -
> -	} else if (copy_from_user(points, user_points,
> -				  sizeof(uint64_t) * count)) {
> -		timeout = -EFAULT;
> -		goto err_free_points;
> -	}
> +	if (user_points &&
> +	    !access_ok(user_points, count * sizeof(*user_points)))
> +		return -EFAULT;
>   
>   	entries = kcalloc(count, sizeof(*entries), GFP_KERNEL);
> -	if (!entries) {
> -		timeout = -ENOMEM;
> -		goto err_free_points;
> -	}
> +	if (!entries)
> +		return -ENOMEM;
> +
>   	/* Walk the list of sync objects and initialize entries.  We do
>   	 * this up-front so that we can properly return -EINVAL if there is
>   	 * a syncobj with a missing fence and then never have the chance of
> @@ -1074,9 +1063,14 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
>   		struct dma_fence *fence;
>   
>   		entries[i].task = current;
> -		entries[i].point = points[i];
> +		if (user_points &&
> +		    __get_user(entries[i].point, user_points++)) {
> +			timeout = -EFAULT;
> +			goto cleanup_entries;
> +		}
>   		fence = drm_syncobj_fence_get(syncobjs[i]);
> -		if (!fence || dma_fence_chain_find_seqno(&fence, points[i])) {
> +		if (!fence ||
> +		    dma_fence_chain_find_seqno(&fence, entries[i].point)) {
>   			dma_fence_put(fence);
>   			if (flags & (DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT |
>   				     DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE)) {
> @@ -1182,9 +1176,6 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
>   	}
>   	kfree(entries);
>   
> -err_free_points:
> -	kfree(points);
> -
>   	return timeout;
>   }
>   



More information about the dri-devel mailing list