All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Wilson <chris-Y6uKTt2uX1cEflXRtASbqLVCufUGDwFn@public.gmane.org>
To: Dave Airlie <airlied-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
Subject: Re: [PATCH 1/4] sync_file: add a mutex to protect fence and callback members. (v3)
Date: Mon, 20 Mar 2017 08:16:36 +0000	[thread overview]
Message-ID: <20170320081636.GB9959@nuc-i3427.alporthouse.com> (raw)
In-Reply-To: <20170320070307.18344-2-airlied-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On Mon, Mar 20, 2017 at 05:03:04PM +1000, Dave Airlie wrote:
> From: Dave Airlie <airlied@redhat.com>
> 
> This patch allows the underlying fence in a sync_file to be changed
> or set to NULL. This isn't currently required but for Vulkan
> semaphores we need to be able to swap and reset the fence.
> 
> In order to faciliate this, it uses rcu to protect the fence,
> along with a new mutex. The mutex also protects the callback.
> It also checks for NULL when retrieving the rcu protected
> fence in case it has been reset.
> 
> v1.1: fix the locking (Julia Lawall).
> v2: use rcu try one
> v3: fix poll to use proper rcu, fixup merge/fill ioctls
> to not crash on NULL fence cases.
> 
> Signed-off-by: Dave Airlie <airlied@redhat.com>
> ---
> @@ -80,7 +87,9 @@ struct sync_file *sync_file_create(struct dma_fence *fence)
>  	if (!sync_file)
>  		return NULL;
>  
> -	sync_file->fence = dma_fence_get(fence);
> +	dma_fence_get(fence);
> +
> +	RCU_INIT_POINTER(sync_file->fence, fence);
>  
>  	snprintf(sync_file->name, sizeof(sync_file->name), "%s-%s%llu-%d",
>  		 fence->ops->get_driver_name(fence),
> @@ -124,13 +133,26 @@ struct dma_fence *sync_file_get_fence(int fd)
>  	if (!sync_file)
>  		return NULL;
>  
> -	fence = dma_fence_get(sync_file->fence);
> +	if (!rcu_access_pointer(sync_file->fence))
> +		return NULL;

Missed fput.

> +
> +	rcu_read_lock();
> +	fence = dma_fence_get_rcu_safe(&sync_file->fence);
> +	rcu_read_unlock();
> +
>  	fput(sync_file->file);
>  
>  	return fence;
>  }
>  EXPORT_SYMBOL(sync_file_get_fence);
>  
> @@ -204,10 +234,16 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,
>  	if (!sync_file)
>  		return NULL;
>  
> +	mutex_lock(&a->lock);
> +	mutex_lock(&b->lock);

This allows userspace to trigger lockdep (just merge the same pair of
sync_files again in opposite order). if (b < a) swap(a, b); ?

>  	a_fences = get_fences(a, &a_num_fences);
>  	b_fences = get_fences(b, &b_num_fences);
> -	if (a_num_fences > INT_MAX - b_num_fences)
> -		return NULL;
> +	if (!a_num_fences || !b_num_fences)
> +		goto unlock;
> +
> +	if (a_num_fences > INT_MAX - b_num_fences) {
> +		goto unlock;
> +	}
>  
>  	num_fences = a_num_fences + b_num_fences;
>  
> @@ -281,10 +323,15 @@ static void sync_file_free(struct kref *kref)
>  {
>  	struct sync_file *sync_file = container_of(kref, struct sync_file,
>  						     kref);
> +	struct dma_fence *fence;
> +

Somewhere, here?, it would be useful to add a comment that the rcu
delayed free is provided by fput.

> +	fence = rcu_dereference_protected(sync_file->fence, 1);
> +	if (fence) {
> +		if (test_bit(POLL_ENABLED, &fence->flags))
> +			dma_fence_remove_callback(fence, &sync_file->cb);
> +		dma_fence_put(fence);
> +	}
>  
> -	if (test_bit(POLL_ENABLED, &sync_file->fence->flags))
> -		dma_fence_remove_callback(sync_file->fence, &sync_file->cb);
> -	dma_fence_put(sync_file->fence);
>  	kfree(sync_file);
>  }
>  
> @@ -299,16 +346,25 @@ static int sync_file_release(struct inode *inode, struct file *file)
>  static unsigned int sync_file_poll(struct file *file, poll_table *wait)
>  {
>  	struct sync_file *sync_file = file->private_data;
> +	unsigned int ret_val = 0;
> +	struct dma_fence *fence;
>  
>  	poll_wait(file, &sync_file->wq, wait);
>  
> -	if (!test_and_set_bit(POLL_ENABLED, &sync_file->fence->flags)) {
> -		if (dma_fence_add_callback(sync_file->fence, &sync_file->cb,
> -					   fence_check_cb_func) < 0)
> -			wake_up_all(&sync_file->wq);
> +	mutex_lock(&sync_file->lock);
> +
> +	fence = sync_file_get_fence_locked(sync_file);

Why do you need the locked version here and not just the rcu variant?

> +	if (fence) {
> +		if (!test_and_set_bit(POLL_ENABLED, &fence->flags)) {
> +			if (dma_fence_add_callback(fence, &sync_file->cb,
> +						   fence_check_cb_func) < 0)
> +				wake_up_all(&sync_file->wq);
> +		}
> +		ret_val = dma_fence_is_signaled(fence) ? POLLIN : 0;
>  	}
> +	mutex_unlock(&sync_file->lock);

So an empty sync_file is incomplete and blocks forever? Why? It's the
opposite behaviour to e.g. reservation_object so a quick explanation of
how that is used by VkSemaphore will cement the differences.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

  parent reply	other threads:[~2017-03-20  8:16 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-20  7:03 [rfc/repost] amdgpu/sync_file shared semaphores Dave Airlie
2017-03-20  7:03 ` [PATCH 2/4] sync_file: add replace and export some functionality (v2) Dave Airlie
     [not found] ` <20170320070307.18344-1-airlied-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-03-20  7:03   ` [PATCH 1/4] sync_file: add a mutex to protect fence and callback members. (v3) Dave Airlie
     [not found]     ` <20170320070307.18344-2-airlied-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-03-20  8:16       ` Chris Wilson [this message]
2017-03-20  8:41         ` Daniel Vetter
2017-03-20  8:21       ` Chris Wilson
2017-03-20  7:03   ` [PATCH 3/4] amdgpu/cs: split out fence dependency checking Dave Airlie
2017-03-20  7:03 ` [PATCH 4/4] amdgpu: use sync file for shared semaphores Dave Airlie
2017-03-20  8:42 ` [rfc/repost] amdgpu/sync_file " Daniel Vetter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170320081636.GB9959@nuc-i3427.alporthouse.com \
    --to=chris-y6uktt2ux1ceflxrtasbqlvcufugdwfn@public.gmane.org \
    --cc=airlied-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    --cc=dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.