Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1430180 > unrolled thread

Re: [RFC 5/5] dma-buf/sync_file: rework fence storage in struct file

Started byChris Wilson <chris@chris-wilson.co.uk>
First post2016-06-23 23:30 +0200
Last post2016-06-24 15:30 +0200
Articles 2 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: [RFC 5/5] dma-buf/sync_file: rework fence storage in struct file Chris Wilson <chris@chris-wilson.co.uk> - 2016-06-23 23:30 +0200
    Re: [RFC 5/5] dma-buf/sync_file: rework fence storage in struct file Gustavo Padovan <gustavo@padovan.org> - 2016-06-24 15:30 +0200

#1430180 — Re: [RFC 5/5] dma-buf/sync_file: rework fence storage in struct file

FromChris Wilson <chris@chris-wilson.co.uk>
Date2016-06-23 23:30 +0200
SubjectRe: [RFC 5/5] dma-buf/sync_file: rework fence storage in struct file
Message-ID<rNkme-7qp-31@gated-at.bofh.it>
On Thu, Jun 23, 2016 at 12:29:50PM -0300, Gustavo Padovan wrote:
> -static void sync_file_add_pt(struct sync_file *sync_file, int *i,
> +static int sync_file_set_fence(struct sync_file *sync_file,
> +			       struct fence **fences)
> +{
> +	struct fence_array *array;
> +
> +	if (sync_file->num_fences == 1) {
> +		sync_file->fence = fences[0];

Straightforward pointer assignment.

> +	} else {
> +		array = fence_array_create(sync_file->num_fences, fences,
> +					   fence_context_alloc(1), 1, false);
> +		if (!array)
> +			return -ENOMEM;
> +
> +		sync_file->fence = &array->base;

New reference.

Imbalance will promptly go bang after we release the single fence[0].

Would fence_array_create(1, fence) returning fence_get(fence) be too
much of a hack?

I would suggest dropping the exported fence_get_fences() and use a local
instead that could avoid the copy, e.g.

static struct fence *get_fences(struct fence **fence,
				unsigned int *num_fences)
{
	if (fence_is_array(*fence)) {
		struct fence_array *array = to_fence_array(*fence);
		*num_fences = array->num_fences;
		return array->fences;
	} else {
		*num_fences = 1;
		return fence;
	}
}

sync_file_merge() {
	int num_fences, num_a_fences, num_b_fences;
	struct fence **fences, **a_fences, **b_fences;

	a_fences = get_fences(&a, &num_a_fences);
	b_fences = get_fences(&b, &num_b_fences);

	num_fences = num_a_fences + num_b_fences;

>  static void sync_file_free(struct kref *kref)
>  {
>  	struct sync_file *sync_file = container_of(kref, struct sync_file,
>  						     kref);
> -	int i;
> -
> -	for (i = 0; i < sync_file->num_fences; ++i) {
> -		fence_remove_callback(sync_file->cbs[i].fence,
> -				      &sync_file->cbs[i].cb);
> -		fence_put(sync_file->cbs[i].fence);
> -	}
>  
> +	fence_remove_callback(sync_file->fence, &sync_file->cb);
> +	fence_teardown(sync_file->fence);

Hmm. Could we detect the removal of the last callback and propagate that
to the fence_array? (Rather then introduce a manual call to
fence_teardown.)

-- 
Chris Wilson, Intel Open Source Technology Centre

[toc] | [next] | [standalone]


#1430657

FromGustavo Padovan <gustavo@padovan.org>
Date2016-06-24 15:30 +0200
Message-ID<rNzlf-9y-9@gated-at.bofh.it>
In reply to#1430180
2016-06-23 Chris Wilson <chris@chris-wilson.co.uk>:

> On Thu, Jun 23, 2016 at 12:29:50PM -0300, Gustavo Padovan wrote:
> > -static void sync_file_add_pt(struct sync_file *sync_file, int *i,
> > +static int sync_file_set_fence(struct sync_file *sync_file,
> > +			       struct fence **fences)
> > +{
> > +	struct fence_array *array;
> > +
> > +	if (sync_file->num_fences == 1) {
> > +		sync_file->fence = fences[0];
> 
> Straightforward pointer assignment.
> 
> > +	} else {
> > +		array = fence_array_create(sync_file->num_fences, fences,
> > +					   fence_context_alloc(1), 1, false);
> > +		if (!array)
> > +			return -ENOMEM;
> > +
> > +		sync_file->fence = &array->base;
> 
> New reference.
> 
> Imbalance will promptly go bang after we release the single fence[0].
> 
> Would fence_array_create(1, fence) returning fence_get(fence) be too
> much of a hack?
> 
> I would suggest dropping the exported fence_get_fences() and use a local
> instead that could avoid the copy, e.g.
> 
> static struct fence *get_fences(struct fence **fence,
> 				unsigned int *num_fences)
> {
> 	if (fence_is_array(*fence)) {
> 		struct fence_array *array = to_fence_array(*fence);
> 		*num_fences = array->num_fences;
> 		return array->fences;
> 	} else {
> 		*num_fences = 1;
> 		return fence;
> 	}
> }
> 
> sync_file_merge() {
> 	int num_fences, num_a_fences, num_b_fences;
> 	struct fence **fences, **a_fences, **b_fences;
> 
> 	a_fences = get_fences(&a, &num_a_fences);
> 	b_fences = get_fences(&b, &num_b_fences);
> 
> 	num_fences = num_a_fences + num_b_fences;


Yes. That is much cleaner solution. I did this initially but then tried
to come up with .get_fences(), but that was the wrong road.

> 
> >  static void sync_file_free(struct kref *kref)
> >  {
> >  	struct sync_file *sync_file = container_of(kref, struct sync_file,
> >  						     kref);
> > -	int i;
> > -
> > -	for (i = 0; i < sync_file->num_fences; ++i) {
> > -		fence_remove_callback(sync_file->cbs[i].fence,
> > -				      &sync_file->cbs[i].cb);
> > -		fence_put(sync_file->cbs[i].fence);
> > -	}
> >  
> > +	fence_remove_callback(sync_file->fence, &sync_file->cb);
> > +	fence_teardown(sync_file->fence);
> 
> Hmm. Could we detect the removal of the last callback and propagate that
> to the fence_array? (Rather then introduce a manual call to
> fence_teardown.)

Maybe. I'll look into ways to identify that. What I did during the
development of this patch was to have a fence_array_destroy(), but then
I moved to .teardown() in the hope to abstract the diff between fences
and fence_arrays.

	Gustavo

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web