Re: [PATCH 1/4] sync_file: add a mutex to protect fence and callback members. (v3)

2017-03-20 Thread Daniel Vetter
On Mon, Mar 20, 2017 at 08:16:36AM +, Chris Wilson wrote:
> On Mon, Mar 20, 2017 at 05:03:04PM +1000, Dave Airlie wrote:
> > From: Dave Airlie 
> > 
> > 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 
> > ---
> > @@ -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); ?

Do we even need the look? 1) rcu-lookup the fences (which are invariant)
2) merge them 3) create new syncfile for them. I don't see a need for
taking locks here.

> 
> > 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?

+1 :-) I think the lock should only be needed when you update the fence,
everywhere else we should be able to get away with rcu.

> > +   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
>

Re: [PATCH 1/4] sync_file: add a mutex to protect fence and callback members. (v3)

2017-03-20 Thread Chris Wilson
On Mon, Mar 20, 2017 at 05:03:04PM +1000, Dave Airlie wrote:
> From: Dave Airlie 
> 
> 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 
> ---
> @@ -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;
> +
> + rcu_read_lock();
> + fence = dma_fence_get_rcu_safe(&sync_file->fence);
> + rcu_read_unlock();
> +
>   fput(sync_file->file);

So poll will wait until the fence is set before the sync_file is
signaled, but here we return NULL. At the moment this is interpretted by
the callers as an error (since we can't distinguish between the lookup
error and the empty sync_file). However, if it is empty we also want to
delay the dependent execution until the fence is set to match the poll
semantics.
-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


Re: [PATCH 1/4] sync_file: add a mutex to protect fence and callback members. (v3)

2017-03-20 Thread Chris Wilson
On Mon, Mar 20, 2017 at 05:03:04PM +1000, Dave Airlie wrote:
> From: Dave Airlie 
> 
> 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 
> ---
> @@ -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


[PATCH 1/4] sync_file: add a mutex to protect fence and callback members. (v3)

2017-03-20 Thread Dave Airlie
From: Dave Airlie 

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 
---
 drivers/dma-buf/sync_file.c | 112 +++-
 include/linux/sync_file.h   |   5 +-
 2 files changed, 94 insertions(+), 23 deletions(-)

diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c
index 2321035..dcba931 100644
--- a/drivers/dma-buf/sync_file.c
+++ b/drivers/dma-buf/sync_file.c
@@ -28,6 +28,10 @@
 
 static const struct file_operations sync_file_fops;
 
+#define sync_file_held(obj) lockdep_is_held(&(obj)->lock)
+#define sync_file_assert_held(obj) \
+   lockdep_assert_held(&(obj)->lock)
+
 static struct sync_file *sync_file_alloc(void)
 {
struct sync_file *sync_file;
@@ -47,6 +51,9 @@ static struct sync_file *sync_file_alloc(void)
 
INIT_LIST_HEAD(&sync_file->cb.node);
 
+   RCU_INIT_POINTER(sync_file->fence, NULL);
+
+   mutex_init(&sync_file->lock);
return sync_file;
 
 err:
@@ -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;
+
+   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);
 
+static inline struct dma_fence *
+sync_file_get_fence_locked(struct sync_file *sync_file)
+{
+   return rcu_dereference_protected(sync_file->fence,
+sync_file_held(sync_file));
+}
+
 static int sync_file_set_fence(struct sync_file *sync_file,
   struct dma_fence **fences, int num_fences)
 {
@@ -143,7 +165,7 @@ static int sync_file_set_fence(struct sync_file *sync_file,
 * we own the reference of the dma_fence_array creation.
 */
if (num_fences == 1) {
-   sync_file->fence = fences[0];
+   RCU_INIT_POINTER(sync_file->fence, fences[0]);
kfree(fences);
} else {
array = dma_fence_array_create(num_fences, fences,
@@ -152,17 +174,25 @@ static int sync_file_set_fence(struct sync_file 
*sync_file,
if (!array)
return -ENOMEM;
 
-   sync_file->fence = &array->base;
+   RCU_INIT_POINTER(sync_file->fence, &array->base);
}
 
return 0;
 }
 
+/* must be called with sync_file lock taken */
 static struct dma_fence **get_fences(struct sync_file *sync_file,
 int *num_fences)
 {
-   if (dma_fence_is_array(sync_file->fence)) {
-   struct dma_fence_array *array = 
to_dma_fence_array(sync_file->fence);
+   struct dma_fence *fence = sync_file_get_fence_locked(sync_file);
+
+   if (!fence) {
+   *num_fences = 0;
+   return NULL;
+   }
+
+   if (dma_fence_is_array(fence)) {
+   struct dma_fence_array *array = to_dma_fence_array(fence);
 
*num_fences = array->num_fences;
return array->fences;
@@ -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);
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;
 
@@ -268,11 +304,17 @@ static struct sync_file *sync_file_merge(const char 
*name, struct sync_file *a,
goto err;
}
 
+   mutex_unlock(&b->lock);
+   mutex_unlock(&a->lock);
+
strlcpy(sync_file->name, name, sizeof(sync_file->nam

[PATCH 1/4] sync_file: add a mutex to protect fence and callback members. (v22)

2017-03-14 Thread Dave Airlie
From: Dave Airlie 

This isn't needed currently, but to reuse sync file for Vulkan
permanent shared semaphore semantics, we need to be able to swap
the fence backing a sync file. This patch adds a mutex to the
sync file and uses to protect accesses to the fence and cb members.

v1.1: fix the locking (Julia Lawall).
v2: use rcu try one

Signed-off-by: Dave Airlie 
---
 drivers/dma-buf/sync_file.c | 82 +++--
 include/linux/sync_file.h   |  5 ++-
 2 files changed, 69 insertions(+), 18 deletions(-)

diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c
index 2321035..8b34f21 100644
--- a/drivers/dma-buf/sync_file.c
+++ b/drivers/dma-buf/sync_file.c
@@ -28,6 +28,10 @@
 
 static const struct file_operations sync_file_fops;
 
+#define sync_file_held(obj) lockdep_is_held(&(obj)->lock)
+#define sync_file_assert_held(obj) \
+   lockdep_assert_held(&(obj)->lock)
+
 static struct sync_file *sync_file_alloc(void)
 {
struct sync_file *sync_file;
@@ -47,6 +51,9 @@ static struct sync_file *sync_file_alloc(void)
 
INIT_LIST_HEAD(&sync_file->cb.node);
 
+   RCU_INIT_POINTER(sync_file->fence, NULL);
+
+   mutex_init(&sync_file->lock);
return sync_file;
 
 err:
@@ -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;
+
+   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);
 
+static inline struct dma_fence *
+sync_file_get_fence_locked(struct sync_file *sync_file)
+{
+   return rcu_dereference_protected(sync_file->fence,
+sync_file_held(sync_file));
+}
+
 static int sync_file_set_fence(struct sync_file *sync_file,
   struct dma_fence **fences, int num_fences)
 {
@@ -143,7 +165,7 @@ static int sync_file_set_fence(struct sync_file *sync_file,
 * we own the reference of the dma_fence_array creation.
 */
if (num_fences == 1) {
-   sync_file->fence = fences[0];
+   RCU_INIT_POINTER(sync_file->fence, fences[0]);
kfree(fences);
} else {
array = dma_fence_array_create(num_fences, fences,
@@ -152,17 +174,20 @@ static int sync_file_set_fence(struct sync_file 
*sync_file,
if (!array)
return -ENOMEM;
 
-   sync_file->fence = &array->base;
+   RCU_INIT_POINTER(sync_file->fence, &array->base);
}
 
return 0;
 }
 
+/* must be called with sync_file lock taken */
 static struct dma_fence **get_fences(struct sync_file *sync_file,
 int *num_fences)
 {
-   if (dma_fence_is_array(sync_file->fence)) {
-   struct dma_fence_array *array = 
to_dma_fence_array(sync_file->fence);
+   struct dma_fence *fence = sync_file_get_fence_locked(sync_file);
+
+   if (dma_fence_is_array(fence)) {
+   struct dma_fence_array *array = to_dma_fence_array(fence);
 
*num_fences = array->num_fences;
return array->fences;
@@ -204,10 +229,13 @@ 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);
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 > INT_MAX - b_num_fences) {
+   goto unlock;
+   }
 
num_fences = a_num_fences + b_num_fences;
 
@@ -268,11 +296,17 @@ static struct sync_file *sync_file_merge(const char 
*name, struct sync_file *a,
goto err;
}
 
+   mutex_unlock(&b->lock);
+   mutex_unlock(&a->lock);
+
strlcpy(sync_file->name, name, sizeof(sync_file->name));
return sync_file;
 
 err:
fput(sync_file->file);
+unlock:
+   mutex_unlock(&b->lock);
+   mutex_unlock(&a->lock);
return NULL;
 
 }
@@ -281,10 +315,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;

Re: [PATCH 1/4] sync_file: add a mutex to protect fence and callback members.

2017-03-14 Thread Dave Airlie
On 15 March 2017 at 10:47, Dave Airlie  wrote:
> On 14 March 2017 at 19:30, Christian König  wrote:
>> Am 14.03.2017 um 10:29 schrieb Chris Wilson:
>>>
>>> On Tue, Mar 14, 2017 at 10:13:37AM +0100, Christian König wrote:

 Am 14.03.2017 um 09:45 schrieb Daniel Vetter:
>
> On Tue, Mar 14, 2017 at 10:50:51AM +1000, Dave Airlie wrote:
>>
>> From: Dave Airlie 
>>
>> This isn't needed currently, but to reuse sync file for Vulkan
>> permanent shared semaphore semantics, we need to be able to swap
>> the fence backing a sync file. This patch adds a mutex to the
>> sync file and uses to protect accesses to the fence and cb members.
>>
>> Signed-off-by: Dave Airlie 
>
> We've gone to pretty great lengths to rcu-protect all the fence stuff,
> so
> that a peek-only is entirely lockless. Can we haz the same for this pls?

 Yes, just wanted to suggest the same thing.

 Basically you just need the following to retrieve the fence:

 while (sync_file->fence && !(fence = fence_get_rcu(sync_file->fence));
>>>
>>> We even have a helper for that:
>>>
>>> fence = dma_fence_get_rcu_safe(&sync_file->fence);
>>>
>>> (Still going to suggest using a reservation_object rather than an
>>> exclusive-only implementation.)
>>
>>
>> Yeah, thought about that as well. But the reservation object doesn't seem to
>> match the required userspace semantic.
>>
>> E.g. you actually don't want more than one fence it in as far as I
>> understand it.
>
> I don't think a reservation object is what the vulkan semantics ask for.
>

I suppose a reservation object with a single exclusive fence is close enough,
just wouldn't want to create one with non-exclusive fences on it.

Dave.
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH 1/4] sync_file: add a mutex to protect fence and callback members.

2017-03-14 Thread Dave Airlie
On 14 March 2017 at 19:30, Christian König  wrote:
> Am 14.03.2017 um 10:29 schrieb Chris Wilson:
>>
>> On Tue, Mar 14, 2017 at 10:13:37AM +0100, Christian König wrote:
>>>
>>> Am 14.03.2017 um 09:45 schrieb Daniel Vetter:

 On Tue, Mar 14, 2017 at 10:50:51AM +1000, Dave Airlie wrote:
>
> From: Dave Airlie 
>
> This isn't needed currently, but to reuse sync file for Vulkan
> permanent shared semaphore semantics, we need to be able to swap
> the fence backing a sync file. This patch adds a mutex to the
> sync file and uses to protect accesses to the fence and cb members.
>
> Signed-off-by: Dave Airlie 

 We've gone to pretty great lengths to rcu-protect all the fence stuff,
 so
 that a peek-only is entirely lockless. Can we haz the same for this pls?
>>>
>>> Yes, just wanted to suggest the same thing.
>>>
>>> Basically you just need the following to retrieve the fence:
>>>
>>> while (sync_file->fence && !(fence = fence_get_rcu(sync_file->fence));
>>
>> We even have a helper for that:
>>
>> fence = dma_fence_get_rcu_safe(&sync_file->fence);
>>
>> (Still going to suggest using a reservation_object rather than an
>> exclusive-only implementation.)
>
>
> Yeah, thought about that as well. But the reservation object doesn't seem to
> match the required userspace semantic.
>
> E.g. you actually don't want more than one fence it in as far as I
> understand it.

I don't think a reservation object is what the vulkan semantics ask for.

Dave.
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH 1/4] sync_file: add a mutex to protect fence and callback members. (fwd)

2017-03-14 Thread Julia Lawall
Perhaps the mutex on line 410 needs to be considered on line 423.

julia

-- Forwarded message --

Hi Dave,

[auto build test WARNING on drm/drm-next]
[also build test WARNING on v4.11-rc2 next-20170310]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Dave-Airlie/sync_file-add-a-mutex-to-protect-fence-and-callback-members/20170314-155609
base:   git://people.freedesktop.org/~airlied/linux.git drm-next
:: branch date: 52 minutes ago
:: commit date: 52 minutes ago

>> drivers/dma-buf/sync_file.c:423:2-8: preceding lock on line 410

git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout a319d478cdd641742a07f809ddb7c143a0a685e9
vim +423 drivers/dma-buf/sync_file.c

d4cab38e drivers/staging/android/sync_file.c Gustavo Padovan 2016-04-28  404
if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
d4cab38e drivers/staging/android/sync_file.c Gustavo Padovan 2016-04-28  405
return -EFAULT;
d4cab38e drivers/staging/android/sync_file.c Gustavo Padovan 2016-04-28  406
d4cab38e drivers/staging/android/sync_file.c Gustavo Padovan 2016-04-28  407
if (info.flags || info.pad)
d4cab38e drivers/staging/android/sync_file.c Gustavo Padovan 2016-04-28  408
return -EINVAL;
d4cab38e drivers/staging/android/sync_file.c Gustavo Padovan 2016-04-28  409
a319d478 drivers/dma-buf/sync_file.c Dave Airlie 2017-03-14 @410
mutex_lock(&sync_file->lock);
a02b9dc9 drivers/dma-buf/sync_file.c Gustavo Padovan 2016-08-05  411
fences = get_fences(sync_file, &num_fences);
a02b9dc9 drivers/dma-buf/sync_file.c Gustavo Padovan 2016-08-05  412
d4cab38e drivers/staging/android/sync_file.c Gustavo Padovan 2016-04-28  413
/*
d4cab38e drivers/staging/android/sync_file.c Gustavo Padovan 2016-04-28  414
 * Passing num_fences = 0 means that userspace doesn't want to
d4cab38e drivers/staging/android/sync_file.c Gustavo Padovan 2016-04-28  415
 * retrieve any sync_fence_info. If num_fences = 0 we skip filling
d4cab38e drivers/staging/android/sync_file.c Gustavo Padovan 2016-04-28  416
 * sync_fence_info and return the actual number of fences on
d4cab38e drivers/staging/android/sync_file.c Gustavo Padovan 2016-04-28  417
 * info->num_fences.
d4cab38e drivers/staging/android/sync_file.c Gustavo Padovan 2016-04-28  418
 */
d4cab38e drivers/staging/android/sync_file.c Gustavo Padovan 2016-04-28  419
if (!info.num_fences)
d4cab38e drivers/staging/android/sync_file.c Gustavo Padovan 2016-04-28  420
goto no_fences;
d4cab38e drivers/staging/android/sync_file.c Gustavo Padovan 2016-04-28  421
a02b9dc9 drivers/dma-buf/sync_file.c Gustavo Padovan 2016-08-05  422
if (info.num_fences < num_fences)
d4cab38e drivers/staging/android/sync_file.c Gustavo Padovan 2016-04-28 @423
return -EINVAL;
d4cab38e drivers/staging/android/sync_file.c Gustavo Padovan 2016-04-28  424
a02b9dc9 drivers/dma-buf/sync_file.c Gustavo Padovan 2016-08-05  425
size = num_fences * sizeof(*fence_info);
d4cab38e drivers/staging/android/sync_file.c Gustavo Padovan 2016-04-28  426
fence_info = kzalloc(size, GFP_KERNEL);

:: The code at line 423 was first introduced by commit
:: d4cab38e153d62ecd502645390c0289c1b8337df staging/android: prepare 
sync_file for de-staging

:: TO: Gustavo Padovan 
:: CC: Greg Kroah-Hartman 

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH 1/4] sync_file: add a mutex to protect fence and callback members.

2017-03-14 Thread Christian König

Am 14.03.2017 um 10:29 schrieb Chris Wilson:

On Tue, Mar 14, 2017 at 10:13:37AM +0100, Christian König wrote:

Am 14.03.2017 um 09:45 schrieb Daniel Vetter:

On Tue, Mar 14, 2017 at 10:50:51AM +1000, Dave Airlie wrote:

From: Dave Airlie 

This isn't needed currently, but to reuse sync file for Vulkan
permanent shared semaphore semantics, we need to be able to swap
the fence backing a sync file. This patch adds a mutex to the
sync file and uses to protect accesses to the fence and cb members.

Signed-off-by: Dave Airlie 

We've gone to pretty great lengths to rcu-protect all the fence stuff, so
that a peek-only is entirely lockless. Can we haz the same for this pls?

Yes, just wanted to suggest the same thing.

Basically you just need the following to retrieve the fence:

while (sync_file->fence && !(fence = fence_get_rcu(sync_file->fence));

We even have a helper for that:

fence = dma_fence_get_rcu_safe(&sync_file->fence);

(Still going to suggest using a reservation_object rather than an
exclusive-only implementation.)


Yeah, thought about that as well. But the reservation object doesn't 
seem to match the required userspace semantic.


E.g. you actually don't want more than one fence it in as far as I 
understand it.


Christian.


-Chris



___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH 1/4] sync_file: add a mutex to protect fence and callback members.

2017-03-14 Thread Chris Wilson
On Tue, Mar 14, 2017 at 10:13:37AM +0100, Christian König wrote:
> Am 14.03.2017 um 09:45 schrieb Daniel Vetter:
> >On Tue, Mar 14, 2017 at 10:50:51AM +1000, Dave Airlie wrote:
> >>From: Dave Airlie 
> >>
> >>This isn't needed currently, but to reuse sync file for Vulkan
> >>permanent shared semaphore semantics, we need to be able to swap
> >>the fence backing a sync file. This patch adds a mutex to the
> >>sync file and uses to protect accesses to the fence and cb members.
> >>
> >>Signed-off-by: Dave Airlie 
> >We've gone to pretty great lengths to rcu-protect all the fence stuff, so
> >that a peek-only is entirely lockless. Can we haz the same for this pls?
> 
> Yes, just wanted to suggest the same thing.
> 
> Basically you just need the following to retrieve the fence:
> 
> while (sync_file->fence && !(fence = fence_get_rcu(sync_file->fence));

We even have a helper for that:

fence = dma_fence_get_rcu_safe(&sync_file->fence);

(Still going to suggest using a reservation_object rather than an
exclusive-only implementation.)
-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


Re: [PATCH 1/4] sync_file: add a mutex to protect fence and callback members.

2017-03-14 Thread Christian König

Am 14.03.2017 um 09:45 schrieb Daniel Vetter:

On Tue, Mar 14, 2017 at 10:50:51AM +1000, Dave Airlie wrote:

From: Dave Airlie 

This isn't needed currently, but to reuse sync file for Vulkan
permanent shared semaphore semantics, we need to be able to swap
the fence backing a sync file. This patch adds a mutex to the
sync file and uses to protect accesses to the fence and cb members.

Signed-off-by: Dave Airlie 

We've gone to pretty great lengths to rcu-protect all the fence stuff, so
that a peek-only is entirely lockless. Can we haz the same for this pls?


Yes, just wanted to suggest the same thing.

Basically you just need the following to retrieve the fence:

while (sync_file->fence && !(fence = fence_get_rcu(sync_file->fence));

And then only taking a look when replacing it.


Yes I know it's probably going to be slightly nasty when you get around to
implementing the replacement logic. For just normal fences we can probably
get away with not doing an rcu dance when freeing it, since the
refcounting should protect us already.


The only tricky thing I can see is the fence_callback structure in the 
sync file. And that can be handled while holding the lock in the replace 
function.



But for the replacement you need to have an rcu-delayed fence_put on the
old fences.


Freeing fences is RCU save anyway, see the default implementation of 
fence_free().


Had to fix that in amdgpu and radeon because our private implementation 
wasn't RCU save and we run into problems because of that.


So at least that should already been taken care of.

Christian.


-Daniel

---
  drivers/dma-buf/sync_file.c | 23 +++
  include/linux/sync_file.h   |  3 +++
  2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c
index 2321035..105f48c 100644
--- a/drivers/dma-buf/sync_file.c
+++ b/drivers/dma-buf/sync_file.c
@@ -47,6 +47,7 @@ static struct sync_file *sync_file_alloc(void)
  
  	INIT_LIST_HEAD(&sync_file->cb.node);
  
+	mutex_init(&sync_file->lock);

return sync_file;
  
  err:

@@ -204,10 +205,13 @@ 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);
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 > INT_MAX - b_num_fences) {
+   goto unlock;
+   }
  
  	num_fences = a_num_fences + b_num_fences;
  
@@ -268,11 +272,17 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,

goto err;
}
  
+	mutex_unlock(&b->lock);

+   mutex_unlock(&a->lock);
+
strlcpy(sync_file->name, name, sizeof(sync_file->name));
return sync_file;
  
  err:

fput(sync_file->file);
+unlock:
+   mutex_unlock(&b->lock);
+   mutex_unlock(&a->lock);
return NULL;
  
  }

@@ -299,16 +309,20 @@ 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;
  
  	poll_wait(file, &sync_file->wq, wait);
  
+	mutex_lock(&sync_file->lock);

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);
}
+   ret_val = dma_fence_is_signaled(sync_file->fence) ? POLLIN : 0;
+   mutex_unlock(&sync_file->lock);
  
-	return dma_fence_is_signaled(sync_file->fence) ? POLLIN : 0;

+   return ret_val;
  }
  
  static long sync_file_ioctl_merge(struct sync_file *sync_file,

@@ -393,6 +407,7 @@ static long sync_file_ioctl_fence_info(struct sync_file 
*sync_file,
if (info.flags || info.pad)
return -EINVAL;
  
+	mutex_lock(&sync_file->lock);

fences = get_fences(sync_file, &num_fences);
  
  	/*

@@ -433,7 +448,7 @@ static long sync_file_ioctl_fence_info(struct sync_file 
*sync_file,
  
  out:

kfree(fence_info);
-
+   mutex_unlock(&sync_file->lock);
return ret;
  }
  
diff --git a/include/linux/sync_file.h b/include/linux/sync_file.h

index 3e3ab84..5aef17f 100644
--- a/include/linux/sync_file.h
+++ b/include/linux/sync_file.h
@@ -30,6 +30,7 @@
   * @wq:   wait queue for fence signaling
   * @fence:fence with the fences in the sync_file
   * @cb:   fence callback information
+ * @lock:   mutex to protect fence/cb - used for semaphores
   */
  struct sync_file {
struct file *file;
@@ -43,6 +44,8 @@ struct sync_file {
  
  	struct dma_fence	*fence;

s

Re: [PATCH 1/4] sync_file: add a mutex to protect fence and callback members.

2017-03-14 Thread Daniel Vetter
On Tue, Mar 14, 2017 at 10:50:51AM +1000, Dave Airlie wrote:
> From: Dave Airlie 
> 
> This isn't needed currently, but to reuse sync file for Vulkan
> permanent shared semaphore semantics, we need to be able to swap
> the fence backing a sync file. This patch adds a mutex to the
> sync file and uses to protect accesses to the fence and cb members.
> 
> Signed-off-by: Dave Airlie 

We've gone to pretty great lengths to rcu-protect all the fence stuff, so
that a peek-only is entirely lockless. Can we haz the same for this pls?

Yes I know it's probably going to be slightly nasty when you get around to
implementing the replacement logic. For just normal fences we can probably
get away with not doing an rcu dance when freeing it, since the
refcounting should protect us already.

But for the replacement you need to have an rcu-delayed fence_put on the
old fences.
-Daniel
> ---
>  drivers/dma-buf/sync_file.c | 23 +++
>  include/linux/sync_file.h   |  3 +++
>  2 files changed, 22 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c
> index 2321035..105f48c 100644
> --- a/drivers/dma-buf/sync_file.c
> +++ b/drivers/dma-buf/sync_file.c
> @@ -47,6 +47,7 @@ static struct sync_file *sync_file_alloc(void)
>  
>   INIT_LIST_HEAD(&sync_file->cb.node);
>  
> + mutex_init(&sync_file->lock);
>   return sync_file;
>  
>  err:
> @@ -204,10 +205,13 @@ 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);
>   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 > INT_MAX - b_num_fences) {
> + goto unlock;
> + }
>  
>   num_fences = a_num_fences + b_num_fences;
>  
> @@ -268,11 +272,17 @@ static struct sync_file *sync_file_merge(const char 
> *name, struct sync_file *a,
>   goto err;
>   }
>  
> + mutex_unlock(&b->lock);
> + mutex_unlock(&a->lock);
> +
>   strlcpy(sync_file->name, name, sizeof(sync_file->name));
>   return sync_file;
>  
>  err:
>   fput(sync_file->file);
> +unlock:
> + mutex_unlock(&b->lock);
> + mutex_unlock(&a->lock);
>   return NULL;
>  
>  }
> @@ -299,16 +309,20 @@ 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;
>  
>   poll_wait(file, &sync_file->wq, wait);
>  
> + mutex_lock(&sync_file->lock);
>   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);
>   }
> + ret_val = dma_fence_is_signaled(sync_file->fence) ? POLLIN : 0;
> + mutex_unlock(&sync_file->lock);
>  
> - return dma_fence_is_signaled(sync_file->fence) ? POLLIN : 0;
> + return ret_val;
>  }
>  
>  static long sync_file_ioctl_merge(struct sync_file *sync_file,
> @@ -393,6 +407,7 @@ static long sync_file_ioctl_fence_info(struct sync_file 
> *sync_file,
>   if (info.flags || info.pad)
>   return -EINVAL;
>  
> + mutex_lock(&sync_file->lock);
>   fences = get_fences(sync_file, &num_fences);
>  
>   /*
> @@ -433,7 +448,7 @@ static long sync_file_ioctl_fence_info(struct sync_file 
> *sync_file,
>  
>  out:
>   kfree(fence_info);
> -
> + mutex_unlock(&sync_file->lock);
>   return ret;
>  }
>  
> diff --git a/include/linux/sync_file.h b/include/linux/sync_file.h
> index 3e3ab84..5aef17f 100644
> --- a/include/linux/sync_file.h
> +++ b/include/linux/sync_file.h
> @@ -30,6 +30,7 @@
>   * @wq:  wait queue for fence signaling
>   * @fence:   fence with the fences in the sync_file
>   * @cb:  fence callback information
> + * @lock:   mutex to protect fence/cb - used for semaphores
>   */
>  struct sync_file {
>   struct file *file;
> @@ -43,6 +44,8 @@ struct sync_file {
>  
>   struct dma_fence*fence;
>   struct dma_fence_cb cb;
> + /* protects the fence pointer and cb */
> + struct mutex lock;
>  };
>  
>  #define POLL_ENABLED DMA_FENCE_FLAG_USER_BITS
> -- 
> 2.7.4
> 
> ___
> dri-devel mailing list
> dri-de...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-g

[PATCH 1/4] sync_file: add a mutex to protect fence and callback members.

2017-03-13 Thread Dave Airlie
From: Dave Airlie 

This isn't needed currently, but to reuse sync file for Vulkan
permanent shared semaphore semantics, we need to be able to swap
the fence backing a sync file. This patch adds a mutex to the
sync file and uses to protect accesses to the fence and cb members.

Signed-off-by: Dave Airlie 
---
 drivers/dma-buf/sync_file.c | 23 +++
 include/linux/sync_file.h   |  3 +++
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c
index 2321035..105f48c 100644
--- a/drivers/dma-buf/sync_file.c
+++ b/drivers/dma-buf/sync_file.c
@@ -47,6 +47,7 @@ static struct sync_file *sync_file_alloc(void)
 
INIT_LIST_HEAD(&sync_file->cb.node);
 
+   mutex_init(&sync_file->lock);
return sync_file;
 
 err:
@@ -204,10 +205,13 @@ 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);
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 > INT_MAX - b_num_fences) {
+   goto unlock;
+   }
 
num_fences = a_num_fences + b_num_fences;
 
@@ -268,11 +272,17 @@ static struct sync_file *sync_file_merge(const char 
*name, struct sync_file *a,
goto err;
}
 
+   mutex_unlock(&b->lock);
+   mutex_unlock(&a->lock);
+
strlcpy(sync_file->name, name, sizeof(sync_file->name));
return sync_file;
 
 err:
fput(sync_file->file);
+unlock:
+   mutex_unlock(&b->lock);
+   mutex_unlock(&a->lock);
return NULL;
 
 }
@@ -299,16 +309,20 @@ 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;
 
poll_wait(file, &sync_file->wq, wait);
 
+   mutex_lock(&sync_file->lock);
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);
}
+   ret_val = dma_fence_is_signaled(sync_file->fence) ? POLLIN : 0;
+   mutex_unlock(&sync_file->lock);
 
-   return dma_fence_is_signaled(sync_file->fence) ? POLLIN : 0;
+   return ret_val;
 }
 
 static long sync_file_ioctl_merge(struct sync_file *sync_file,
@@ -393,6 +407,7 @@ static long sync_file_ioctl_fence_info(struct sync_file 
*sync_file,
if (info.flags || info.pad)
return -EINVAL;
 
+   mutex_lock(&sync_file->lock);
fences = get_fences(sync_file, &num_fences);
 
/*
@@ -433,7 +448,7 @@ static long sync_file_ioctl_fence_info(struct sync_file 
*sync_file,
 
 out:
kfree(fence_info);
-
+   mutex_unlock(&sync_file->lock);
return ret;
 }
 
diff --git a/include/linux/sync_file.h b/include/linux/sync_file.h
index 3e3ab84..5aef17f 100644
--- a/include/linux/sync_file.h
+++ b/include/linux/sync_file.h
@@ -30,6 +30,7 @@
  * @wq:wait queue for fence signaling
  * @fence: fence with the fences in the sync_file
  * @cb:fence callback information
+ * @lock:   mutex to protect fence/cb - used for semaphores
  */
 struct sync_file {
struct file *file;
@@ -43,6 +44,8 @@ struct sync_file {
 
struct dma_fence*fence;
struct dma_fence_cb cb;
+   /* protects the fence pointer and cb */
+   struct mutex lock;
 };
 
 #define POLL_ENABLED DMA_FENCE_FLAG_USER_BITS
-- 
2.7.4

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx