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

Reply via email to