[PATCH 1/6] dma-buf: remove shared fence staging in reservation object

Chris Wilson chris at chris-wilson.co.uk
Thu Aug 9 12:08:19 UTC 2018


Quoting Christian König (2018-08-09 12:37:08)
>  void reservation_object_add_shared_fence(struct reservation_object *obj,
>                                          struct dma_fence *fence)
>  {
> -       struct reservation_object_list *old, *fobj = obj->staged;
> +       struct reservation_object_list *fobj;
> +       unsigned int i;
>  
> -       old = reservation_object_get_list(obj);
> -       obj->staged = NULL;
> +       dma_fence_get(fence);
> +
> +       fobj = reservation_object_get_list(obj);
>  
> -       if (!fobj) {
> -               BUG_ON(old->shared_count >= old->shared_max);
> -               reservation_object_add_shared_inplace(obj, old, fence);
> -       } else
> -               reservation_object_add_shared_replace(obj, old, fobj, fence);
> +       preempt_disable();
> +       write_seqcount_begin(&obj->seq);
> +
> +       for (i = 0; i < fobj->shared_count; ++i) {
> +               struct dma_fence *old_fence;
> +
> +               old_fence = rcu_dereference_protected(fobj->shared[i],
> +                                                     reservation_object_held(obj));
> +               if (old_fence->context == fence->context ||
> +                   dma_fence_is_signaled(old_fence)) {

Are you happy with the possibility that the shared[] may contain two
fences belonging to the same context? That was a sticking point earlier.

> +                       /* memory barrier is added by write_seqcount_begin */
> +                       RCU_INIT_POINTER(fobj->shared[i], fence);
> +                       write_seqcount_end(&obj->seq);
> +                       preempt_enable();
> +                       dma_fence_put(old_fence);

You can rearrange this to have a single exit.

       for (i = 0; i < fobj->shared_count; ++i) {
               struct dma_fence *old_fence;

               old_fence = rcu_dereference_protected(fobj->shared[i],
                                                     reservation_object_held(obj));
               if (old_fence->context == fence->context ||
                   dma_fence_is_signaled(old_fence)) {
		   	dma_fence_put(old_fence);
			goto replace;
		}
	}
	fobj->shared_count++;
replace:
       /*
        * memory barrier is added by write_seqcount_begin,
        * fobj->shared_count is protected by this lock too
        */
	RCU_INIT_POINTER(fobj->shared[i], fence);
	write_seqcount_end(&obj->seq);
	preempt_enable();
}
-Chris


More information about the dri-devel mailing list