Re: [PATCH 1/2] dma-buf: make reservation_object_copy_fences rcu save

2017-09-11 Thread Christian König

Am 11.09.2017 um 17:29 schrieb Maarten Lankhorst:

Op 11-09-17 om 17:24 schreef Christian König:

Am 11.09.2017 um 17:22 schrieb Christian König:

Am 11.09.2017 um 17:13 schrieb Maarten Lankhorst:

Op 11-09-17 om 16:45 schreef Christian König:

Am 11.09.2017 um 15:56 schrieb Maarten Lankhorst:

Op 11-09-17 om 14:53 schreef Christian König:

Am 10.09.2017 um 09:30 schrieb Maarten Lankhorst:
[SNIP]

To be honest that looks rather ugly to me for not much gain.

Additional to that we loose the optimization I've stolen from the wait function.

Right now your version does exactly the same as 
reservation_object_get_fences_rcu,
but with a reservation_object_list instead of a fence array.

Well then please take a closer look again:

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

 fence = rcu_dereference(src_list->shared[i]);
 if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
  >flags))
 continue;

 if (!dma_fence_get_rcu(fence)) {
 kfree(dst_list);
 src_list = rcu_dereference(src->fence);
 goto retry;
 }

 if (dma_fence_is_signaled(fence)) {
 dma_fence_put(fence);
 continue;
 }

dst_list->shared[dst_list->shared_count++] = fence;
 }

We only take fences into the new reservation list when they aren't already 
signaled.

This can't be added to reservation_object_get_fences_rcu() because that would 
break VM handling on radeon and amdgpu.

What we could do is adding a function to return all fences (including the 
exclusive one) as reservation_object_list() and use that in both the wait as 
well as the copy function.

Yeah, but I don't see the problem with VM, guessing amdgpu_vm_prt_fini.. why 
would it break if I pruned the signaled fences from the copied list?


Not the PRT stuff would break, but the VM flush handling. Rather long 
story, but basically we need to have the already signaled fences as well 
to correctly update the hardware state.


We could of course handle all that in a single function which gets its 
behavior as parameters, but to be honest I think just having two copies 
of the code which looks almost the same is cleaner.


Regards,
Christian.


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



___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/2] dma-buf: make reservation_object_copy_fences rcu save

2017-09-11 Thread Maarten Lankhorst
Op 11-09-17 om 17:24 schreef Christian König:
> Am 11.09.2017 um 17:22 schrieb Christian König:
>> Am 11.09.2017 um 17:13 schrieb Maarten Lankhorst:
>>> Op 11-09-17 om 16:45 schreef Christian König:
 Am 11.09.2017 um 15:56 schrieb Maarten Lankhorst:
> Op 11-09-17 om 14:53 schreef Christian König:
>> Am 10.09.2017 um 09:30 schrieb Maarten Lankhorst:
>> [SNIP]
 To be honest that looks rather ugly to me for not much gain.

 Additional to that we loose the optimization I've stolen from the wait 
 function.
>>> Right now your version does exactly the same as 
>>> reservation_object_get_fences_rcu,
>>> but with a reservation_object_list instead of a fence array.
>>
>> Well then please take a closer look again:
>>> for (i = 0; i < src_list->shared_count; ++i) {
>>> struct dma_fence *fence;
>>>
>>> fence = rcu_dereference(src_list->shared[i]);
>>> if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
>>>  >flags))
>>> continue;
>>>
>>> if (!dma_fence_get_rcu(fence)) {
>>> kfree(dst_list);
>>> src_list = rcu_dereference(src->fence);
>>> goto retry;
>>> }
>>>
>>> if (dma_fence_is_signaled(fence)) {
>>> dma_fence_put(fence);
>>> continue;
>>> }
>>>
>>> dst_list->shared[dst_list->shared_count++] = fence;
>>> }
>>
>> We only take fences into the new reservation list when they aren't already 
>> signaled.
>>
>> This can't be added to reservation_object_get_fences_rcu() because that 
>> would break VM handling on radeon and amdgpu.
>
> What we could do is adding a function to return all fences (including the 
> exclusive one) as reservation_object_list() and use that in both the wait as 
> well as the copy function. 
Yeah, but I don't see the problem with VM, guessing amdgpu_vm_prt_fini.. why 
would it break if I pruned the signaled fences from the copied list?
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/2] dma-buf: make reservation_object_copy_fences rcu save

2017-09-11 Thread Christian König

Am 11.09.2017 um 17:22 schrieb Christian König:

Am 11.09.2017 um 17:13 schrieb Maarten Lankhorst:

Op 11-09-17 om 16:45 schreef Christian König:

Am 11.09.2017 um 15:56 schrieb Maarten Lankhorst:

Op 11-09-17 om 14:53 schreef Christian König:

Am 10.09.2017 um 09:30 schrieb Maarten Lankhorst:
[SNIP]

To be honest that looks rather ugly to me for not much gain.

Additional to that we loose the optimization I've stolen from the 
wait function.
Right now your version does exactly the same as 
reservation_object_get_fences_rcu,

but with a reservation_object_list instead of a fence array.


Well then please take a closer look again:

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

fence = rcu_dereference(src_list->shared[i]);
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
 >flags))
continue;

if (!dma_fence_get_rcu(fence)) {
kfree(dst_list);
src_list = rcu_dereference(src->fence);
goto retry;
}

if (dma_fence_is_signaled(fence)) {
dma_fence_put(fence);
continue;
}

dst_list->shared[dst_list->shared_count++] = fence;
}


We only take fences into the new reservation list when they aren't 
already signaled.


This can't be added to reservation_object_get_fences_rcu() because 
that would break VM handling on radeon and amdgpu.


What we could do is adding a function to return all fences (including 
the exclusive one) as reservation_object_list() and use that in both the 
wait as well as the copy function.


Regards,
Christian.



Regards,
Christian.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel



___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/2] dma-buf: make reservation_object_copy_fences rcu save

2017-09-11 Thread Christian König

Am 11.09.2017 um 17:13 schrieb Maarten Lankhorst:

Op 11-09-17 om 16:45 schreef Christian König:

Am 11.09.2017 um 15:56 schrieb Maarten Lankhorst:

Op 11-09-17 om 14:53 schreef Christian König:

Am 10.09.2017 um 09:30 schrieb Maarten Lankhorst:
[SNIP]

To be honest that looks rather ugly to me for not much gain.

Additional to that we loose the optimization I've stolen from the wait function.

Right now your version does exactly the same as 
reservation_object_get_fences_rcu,
but with a reservation_object_list instead of a fence array.


Well then please take a closer look again:

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

fence = rcu_dereference(src_list->shared[i]);
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
 >flags))
continue;

if (!dma_fence_get_rcu(fence)) {
kfree(dst_list);
src_list = rcu_dereference(src->fence);
goto retry;
}

if (dma_fence_is_signaled(fence)) {
dma_fence_put(fence);
continue;
}

dst_list->shared[dst_list->shared_count++] = fence;
}


We only take fences into the new reservation list when they aren't 
already signaled.


This can't be added to reservation_object_get_fences_rcu() because that 
would break VM handling on radeon and amdgpu.


Regards,
Christian.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/2] dma-buf: make reservation_object_copy_fences rcu save

2017-09-11 Thread Maarten Lankhorst
Op 11-09-17 om 16:45 schreef Christian König:
> Am 11.09.2017 um 15:56 schrieb Maarten Lankhorst:
>> Op 11-09-17 om 14:53 schreef Christian König:
>>> Am 10.09.2017 um 09:30 schrieb Maarten Lankhorst:
 Op 04-09-17 om 21:02 schreef Christian König:
> From: Christian König 
>
> Stop requiring that the src reservation object is locked for this 
> operation.
>
> Signed-off-by: Christian König 
> ---
>drivers/dma-buf/reservation.c | 56 
> ---
>1 file changed, 42 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
> index dec3a81..b44d9d7 100644
> --- a/drivers/dma-buf/reservation.c
> +++ b/drivers/dma-buf/reservation.c
> @@ -266,8 +266,7 @@ EXPORT_SYMBOL(reservation_object_add_excl_fence);
>* @dst: the destination reservation object
>* @src: the source reservation object
>*
> -* Copy all fences from src to dst. Both src->lock as well as dst-lock 
> must be
> -* held.
> +* Copy all fences from src to dst. dst-lock must be held.
>*/
>int reservation_object_copy_fences(struct reservation_object *dst,
>   struct reservation_object *src)
 Could this be implemented using reservation_object_get_fences_rcu? You're 
 essentially duplicating its functionality.
>>> I've considered this as well, but reservation_object_get_fences_rcu() 
>>> returns an array and here we need an reservation_object_list.
>> Doesn't seem too hard, below is the result from fiddling with the allocation 
>> function..
>> reservation_object_list is just a list of fences with some junk in front.
>>
>> Here you go, but only tested with the compiler. O:)
>> -8<-
>>   drivers/dma-buf/reservation.c | 192 
>> +
>>   1 file changed, 109 insertions(+), 83 deletions(-)
>
> To be honest that looks rather ugly to me for not much gain.
>
> Additional to that we loose the optimization I've stolen from the wait 
> function.

Right now your version does exactly the same as 
reservation_object_get_fences_rcu,
but with a reservation_object_list instead of a fence array.

Can't you change reservation_object_get_fences_rcu to return a
reservation_object_list? All callsites look like they could be easily converted.

So the new patch series would be:
1. Make reservation_object_get_fences_rcu return a reservation_object_list
2. Add optimization
3. Convert reservation_object_copy_fences to use rcu.

Cheers,
Maarten

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/2] dma-buf: make reservation_object_copy_fences rcu save

2017-09-11 Thread Christian König

Am 11.09.2017 um 15:56 schrieb Maarten Lankhorst:

Op 11-09-17 om 14:53 schreef Christian König:

Am 10.09.2017 um 09:30 schrieb Maarten Lankhorst:

Op 04-09-17 om 21:02 schreef Christian König:

From: Christian König 

Stop requiring that the src reservation object is locked for this operation.

Signed-off-by: Christian König 
---
   drivers/dma-buf/reservation.c | 56 
---
   1 file changed, 42 insertions(+), 14 deletions(-)

diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
index dec3a81..b44d9d7 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -266,8 +266,7 @@ EXPORT_SYMBOL(reservation_object_add_excl_fence);
   * @dst: the destination reservation object
   * @src: the source reservation object
   *
-* Copy all fences from src to dst. Both src->lock as well as dst-lock must be
-* held.
+* Copy all fences from src to dst. dst-lock must be held.
   */
   int reservation_object_copy_fences(struct reservation_object *dst,
  struct reservation_object *src)

Could this be implemented using reservation_object_get_fences_rcu? You're 
essentially duplicating its functionality.

I've considered this as well, but reservation_object_get_fences_rcu() returns 
an array and here we need an reservation_object_list.

Doesn't seem too hard, below is the result from fiddling with the allocation 
function..
reservation_object_list is just a list of fences with some junk in front.

Here you go, but only tested with the compiler. O:)
-8<-
  drivers/dma-buf/reservation.c | 192 
+
  1 file changed, 109 insertions(+), 83 deletions(-)


To be honest that looks rather ugly to me for not much gain.

Additional to that we loose the optimization I've stolen from the wait 
function.


Regards,
Christian.



diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
index dec3a815455d..72ee91f34132 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -261,87 +261,43 @@ void reservation_object_add_excl_fence(struct 
reservation_object *obj,
  }
  EXPORT_SYMBOL(reservation_object_add_excl_fence);
  
-/**

-* reservation_object_copy_fences - Copy all fences from src to dst.
-* @dst: the destination reservation object
-* @src: the source reservation object
-*
-* Copy all fences from src to dst. Both src->lock as well as dst-lock must be
-* held.
-*/
-int reservation_object_copy_fences(struct reservation_object *dst,
-  struct reservation_object *src)
+static bool realloc_shared(void **ptr, struct dma_fence ***pshared, unsigned 
shared_max, bool alloc_list, bool unlocked)
  {
-   struct reservation_object_list *src_list, *dst_list;
-   struct dma_fence *old, *new;
-   size_t size;
-   unsigned i;
-
-   src_list = reservation_object_get_list(src);
-
-   if (src_list) {
-   size = offsetof(typeof(*src_list),
-   shared[src_list->shared_count]);
-   dst_list = kmalloc(size, GFP_KERNEL);
-   if (!dst_list)
-   return -ENOMEM;
-
-   dst_list->shared_count = src_list->shared_count;
-   dst_list->shared_max = src_list->shared_count;
-   for (i = 0; i < src_list->shared_count; ++i)
-   dst_list->shared[i] =
-   dma_fence_get(src_list->shared[i]);
-   } else {
-   dst_list = NULL;
-   }
-
-   kfree(dst->staged);
-   dst->staged = NULL;
+   size_t sz;
+   void *newptr;
  
-	src_list = reservation_object_get_list(dst);

+   if (alloc_list)
+   sz = offsetof(struct reservation_object_list, 
shared[shared_max]);
+   else
+   sz = shared_max * sizeof(struct dma_fence *);
  
-	old = reservation_object_get_excl(dst);

-   new = reservation_object_get_excl(src);
+   newptr = krealloc(*ptr, sz, unlocked ? GFP_KERNEL : GFP_NOWAIT | 
__GFP_NOWARN);
+   if (!newptr)
+   return false;
  
-	dma_fence_get(new);

+   *ptr = newptr;
+   if (alloc_list) {
+   struct reservation_object_list *fobj = newptr;
  
-	preempt_disable();

-   write_seqcount_begin(>seq);
-   /* write_seqcount_begin provides the necessary memory barrier */
-   RCU_INIT_POINTER(dst->fence_excl, new);
-   RCU_INIT_POINTER(dst->fence, dst_list);
-   write_seqcount_end(>seq);
-   preempt_enable();
-
-   if (src_list)
-   kfree_rcu(src_list, rcu);
-   dma_fence_put(old);
+   fobj->shared_max = shared_max;
+   *pshared = fobj->shared;
+   } else
+   *pshared = newptr;
  
-	return 0;

+   return true;
  }

Re: [PATCH 1/2] dma-buf: make reservation_object_copy_fences rcu save

2017-09-11 Thread Maarten Lankhorst
Op 11-09-17 om 14:53 schreef Christian König:
> Am 10.09.2017 um 09:30 schrieb Maarten Lankhorst:
>> Op 04-09-17 om 21:02 schreef Christian König:
>>> From: Christian König 
>>>
>>> Stop requiring that the src reservation object is locked for this operation.
>>>
>>> Signed-off-by: Christian König 
>>> ---
>>>   drivers/dma-buf/reservation.c | 56 
>>> ---
>>>   1 file changed, 42 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
>>> index dec3a81..b44d9d7 100644
>>> --- a/drivers/dma-buf/reservation.c
>>> +++ b/drivers/dma-buf/reservation.c
>>> @@ -266,8 +266,7 @@ EXPORT_SYMBOL(reservation_object_add_excl_fence);
>>>   * @dst: the destination reservation object
>>>   * @src: the source reservation object
>>>   *
>>> -* Copy all fences from src to dst. Both src->lock as well as dst-lock must 
>>> be
>>> -* held.
>>> +* Copy all fences from src to dst. dst-lock must be held.
>>>   */
>>>   int reservation_object_copy_fences(struct reservation_object *dst,
>>>  struct reservation_object *src)
>> Could this be implemented using reservation_object_get_fences_rcu? You're 
>> essentially duplicating its functionality.
>
> I've considered this as well, but reservation_object_get_fences_rcu() returns 
> an array and here we need an reservation_object_list. 

Doesn't seem too hard, below is the result from fiddling with the allocation 
function..
reservation_object_list is just a list of fences with some junk in front.

Here you go, but only tested with the compiler. O:)
-8<-
 drivers/dma-buf/reservation.c | 192 
+
 1 file changed, 109 insertions(+), 83 deletions(-)

diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
index dec3a815455d..72ee91f34132 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -261,87 +261,43 @@ void reservation_object_add_excl_fence(struct 
reservation_object *obj,
 }
 EXPORT_SYMBOL(reservation_object_add_excl_fence);
 
-/**
-* reservation_object_copy_fences - Copy all fences from src to dst.
-* @dst: the destination reservation object
-* @src: the source reservation object
-*
-* Copy all fences from src to dst. Both src->lock as well as dst-lock must be
-* held.
-*/
-int reservation_object_copy_fences(struct reservation_object *dst,
-  struct reservation_object *src)
+static bool realloc_shared(void **ptr, struct dma_fence ***pshared, unsigned 
shared_max, bool alloc_list, bool unlocked)
 {
-   struct reservation_object_list *src_list, *dst_list;
-   struct dma_fence *old, *new;
-   size_t size;
-   unsigned i;
-
-   src_list = reservation_object_get_list(src);
-
-   if (src_list) {
-   size = offsetof(typeof(*src_list),
-   shared[src_list->shared_count]);
-   dst_list = kmalloc(size, GFP_KERNEL);
-   if (!dst_list)
-   return -ENOMEM;
-
-   dst_list->shared_count = src_list->shared_count;
-   dst_list->shared_max = src_list->shared_count;
-   for (i = 0; i < src_list->shared_count; ++i)
-   dst_list->shared[i] =
-   dma_fence_get(src_list->shared[i]);
-   } else {
-   dst_list = NULL;
-   }
-
-   kfree(dst->staged);
-   dst->staged = NULL;
+   size_t sz;
+   void *newptr;
 
-   src_list = reservation_object_get_list(dst);
+   if (alloc_list)
+   sz = offsetof(struct reservation_object_list, 
shared[shared_max]);
+   else
+   sz = shared_max * sizeof(struct dma_fence *);
 
-   old = reservation_object_get_excl(dst);
-   new = reservation_object_get_excl(src);
+   newptr = krealloc(*ptr, sz, unlocked ? GFP_KERNEL : GFP_NOWAIT | 
__GFP_NOWARN);
+   if (!newptr)
+   return false;
 
-   dma_fence_get(new);
+   *ptr = newptr;
+   if (alloc_list) {
+   struct reservation_object_list *fobj = newptr;
 
-   preempt_disable();
-   write_seqcount_begin(>seq);
-   /* write_seqcount_begin provides the necessary memory barrier */
-   RCU_INIT_POINTER(dst->fence_excl, new);
-   RCU_INIT_POINTER(dst->fence, dst_list);
-   write_seqcount_end(>seq);
-   preempt_enable();
-
-   if (src_list)
-   kfree_rcu(src_list, rcu);
-   dma_fence_put(old);
+   fobj->shared_max = shared_max;
+   *pshared = fobj->shared;
+   } else
+   *pshared = newptr;
 
-   return 0;
+   return true;
 }
-EXPORT_SYMBOL(reservation_object_copy_fences);
 
-/**
- * reservation_object_get_fences_rcu - Get an object's shared 

Re: [PATCH 1/2] dma-buf: make reservation_object_copy_fences rcu save

2017-09-11 Thread Christian König

Am 10.09.2017 um 09:30 schrieb Maarten Lankhorst:

Op 04-09-17 om 21:02 schreef Christian König:

From: Christian König 

Stop requiring that the src reservation object is locked for this operation.

Signed-off-by: Christian König 
---
  drivers/dma-buf/reservation.c | 56 ---
  1 file changed, 42 insertions(+), 14 deletions(-)

diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
index dec3a81..b44d9d7 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -266,8 +266,7 @@ EXPORT_SYMBOL(reservation_object_add_excl_fence);
  * @dst: the destination reservation object
  * @src: the source reservation object
  *
-* Copy all fences from src to dst. Both src->lock as well as dst-lock must be
-* held.
+* Copy all fences from src to dst. dst-lock must be held.
  */
  int reservation_object_copy_fences(struct reservation_object *dst,
   struct reservation_object *src)

Could this be implemented using reservation_object_get_fences_rcu? You're 
essentially duplicating its functionality.


I've considered this as well, but reservation_object_get_fences_rcu() 
returns an array and here we need an reservation_object_list.


Regards,
Christian.



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



___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/2] dma-buf: make reservation_object_copy_fences rcu save

2017-09-10 Thread Maarten Lankhorst
Op 04-09-17 om 21:02 schreef Christian König:
> From: Christian König 
>
> Stop requiring that the src reservation object is locked for this operation.
>
> Signed-off-by: Christian König 
> ---
>  drivers/dma-buf/reservation.c | 56 
> ---
>  1 file changed, 42 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
> index dec3a81..b44d9d7 100644
> --- a/drivers/dma-buf/reservation.c
> +++ b/drivers/dma-buf/reservation.c
> @@ -266,8 +266,7 @@ EXPORT_SYMBOL(reservation_object_add_excl_fence);
>  * @dst: the destination reservation object
>  * @src: the source reservation object
>  *
> -* Copy all fences from src to dst. Both src->lock as well as dst-lock must be
> -* held.
> +* Copy all fences from src to dst. dst-lock must be held.
>  */
>  int reservation_object_copy_fences(struct reservation_object *dst,
>  struct reservation_object *src)
Could this be implemented using reservation_object_get_fences_rcu? You're 
essentially duplicating its functionality.

Cheers,
Maarten
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/2] dma-buf: make reservation_object_copy_fences rcu save

2017-09-08 Thread Daniel Vetter
On Thu, Sep 07, 2017 at 09:13:32AM +0200, Christian König wrote:
> Ping? David can you take a look?
> 
> Alex is on vacation and that is a rather important bug fix.

Works better when you cc Gustavo/Maarten/Sumits/Chris I think, for
anything dma-buf review needing.
-Daniel

> 
> Thanks,
> Christian.
> 
> Am 04.09.2017 um 21:02 schrieb Christian König:
> > From: Christian König 
> > 
> > Stop requiring that the src reservation object is locked for this operation.
> > 
> > Signed-off-by: Christian König 
> > ---
> >   drivers/dma-buf/reservation.c | 56 
> > ---
> >   1 file changed, 42 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
> > index dec3a81..b44d9d7 100644
> > --- a/drivers/dma-buf/reservation.c
> > +++ b/drivers/dma-buf/reservation.c
> > @@ -266,8 +266,7 @@ EXPORT_SYMBOL(reservation_object_add_excl_fence);
> >   * @dst: the destination reservation object
> >   * @src: the source reservation object
> >   *
> > -* Copy all fences from src to dst. Both src->lock as well as dst-lock must 
> > be
> > -* held.
> > +* Copy all fences from src to dst. dst-lock must be held.
> >   */
> >   int reservation_object_copy_fences(struct reservation_object *dst,
> >struct reservation_object *src)
> > @@ -277,33 +276,62 @@ int reservation_object_copy_fences(struct 
> > reservation_object *dst,
> > size_t size;
> > unsigned i;
> > -   src_list = reservation_object_get_list(src);
> > +   rcu_read_lock();
> > +   src_list = rcu_dereference(src->fence);
> > +retry:
> > if (src_list) {
> > -   size = offsetof(typeof(*src_list),
> > -   shared[src_list->shared_count]);
> > +   unsigned shared_count = src_list->shared_count;
> > +
> > +   size = offsetof(typeof(*src_list), shared[shared_count]);
> > +   rcu_read_unlock();
> > +
> > dst_list = kmalloc(size, GFP_KERNEL);
> > if (!dst_list)
> > return -ENOMEM;
> > -   dst_list->shared_count = src_list->shared_count;
> > -   dst_list->shared_max = src_list->shared_count;
> > -   for (i = 0; i < src_list->shared_count; ++i)
> > -   dst_list->shared[i] =
> > -   dma_fence_get(src_list->shared[i]);
> > +   rcu_read_lock();
> > +   src_list = rcu_dereference(src->fence);
> > +   if (!src_list || src_list->shared_count > shared_count) {
> > +   kfree(dst_list);
> > +   goto retry;
> > +   }
> > +
> > +   dst_list->shared_count = 0;
> > +   dst_list->shared_max = shared_count;
> > +   for (i = 0; i < src_list->shared_count; ++i) {
> > +   struct dma_fence *fence;
> > +
> > +   fence = rcu_dereference(src_list->shared[i]);
> > +   if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
> > +>flags))
> > +   continue;
> > +
> > +   if (!dma_fence_get_rcu(fence)) {
> > +   kfree(dst_list);
> > +   src_list = rcu_dereference(src->fence);
> > +   goto retry;
> > +   }
> > +
> > +   if (dma_fence_is_signaled(fence)) {
> > +   dma_fence_put(fence);
> > +   continue;
> > +   }
> > +
> > +   dst_list->shared[dst_list->shared_count++] = fence;
> > +   }
> > } else {
> > dst_list = NULL;
> > }
> > +   new = dma_fence_get_rcu_safe(>fence_excl);
> > +   rcu_read_unlock();
> > +
> > kfree(dst->staged);
> > dst->staged = NULL;
> > src_list = reservation_object_get_list(dst);
> > -
> > old = reservation_object_get_excl(dst);
> > -   new = reservation_object_get_excl(src);
> > -
> > -   dma_fence_get(new);
> > preempt_disable();
> > write_seqcount_begin(>seq);
> 
> 
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

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


Re: [PATCH 1/2] dma-buf: make reservation_object_copy_fences rcu save

2017-09-07 Thread zhoucm1



On 2017年09月07日 15:13, Christian König wrote:

Ping? David can you take a look?

Alex is on vacation and that is a rather important bug fix.

Thanks,
Christian.

Am 04.09.2017 um 21:02 schrieb Christian König:

From: Christian König 

Stop requiring that the src reservation object is locked for this 
operation.


Signed-off-by: Christian König 
---
  drivers/dma-buf/reservation.c | 56 
---

  1 file changed, 42 insertions(+), 14 deletions(-)

diff --git a/drivers/dma-buf/reservation.c 
b/drivers/dma-buf/reservation.c

index dec3a81..b44d9d7 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -266,8 +266,7 @@ EXPORT_SYMBOL(reservation_object_add_excl_fence);
  * @dst: the destination reservation object
  * @src: the source reservation object
  *
-* Copy all fences from src to dst. Both src->lock as well as 
dst-lock must be

-* held.
+* Copy all fences from src to dst. dst-lock must be held.
  */
  int reservation_object_copy_fences(struct reservation_object *dst,
 struct reservation_object *src)
@@ -277,33 +276,62 @@ int reservation_object_copy_fences(struct 
reservation_object *dst,

  size_t size;
  unsigned i;
  -src_list = reservation_object_get_list(src);
+rcu_read_lock();
+src_list = rcu_dereference(src->fence);
  +retry:
  if (src_list) {
-size = offsetof(typeof(*src_list),
-shared[src_list->shared_count]);
+unsigned shared_count = src_list->shared_count;
+
+size = offsetof(typeof(*src_list), shared[shared_count]);
+rcu_read_unlock();
+
  dst_list = kmalloc(size, GFP_KERNEL);
  if (!dst_list)
  return -ENOMEM;
  -dst_list->shared_count = src_list->shared_count;
-dst_list->shared_max = src_list->shared_count;
-for (i = 0; i < src_list->shared_count; ++i)
-dst_list->shared[i] =
-dma_fence_get(src_list->shared[i]);
+rcu_read_lock();
+src_list = rcu_dereference(src->fence);
+if (!src_list || src_list->shared_count > shared_count) {
+kfree(dst_list);
+goto retry;
+}
+
+dst_list->shared_count = 0;
+dst_list->shared_max = shared_count;
+for (i = 0; i < src_list->shared_count; ++i) {
+struct dma_fence *fence;
+
+fence = rcu_dereference(src_list->shared[i]);
+if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
+ >flags))
seems here is duplicated with the below dma_fence_is_signaled, can it be 
removed?


And I'm not sure the locking, but it looks good, so Acked-by: Chunming 
Zhou 

+continue;
+
+if (!dma_fence_get_rcu(fence)) {
+kfree(dst_list);
+src_list = rcu_dereference(src->fence);
+goto retry;
+}
+
+if (dma_fence_is_signaled(fence)) {
+dma_fence_put(fence);
+continue;
+}
+
+dst_list->shared[dst_list->shared_count++] = fence;
+}
  } else {
  dst_list = NULL;
  }
  +new = dma_fence_get_rcu_safe(>fence_excl);
+rcu_read_unlock();
+
  kfree(dst->staged);
  dst->staged = NULL;
src_list = reservation_object_get_list(dst);
-
  old = reservation_object_get_excl(dst);
-new = reservation_object_get_excl(src);
-
-dma_fence_get(new);
preempt_disable();
  write_seqcount_begin(>seq);





___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/2] dma-buf: make reservation_object_copy_fences rcu save

2017-09-07 Thread Christian König

Ping? David can you take a look?

Alex is on vacation and that is a rather important bug fix.

Thanks,
Christian.

Am 04.09.2017 um 21:02 schrieb Christian König:

From: Christian König 

Stop requiring that the src reservation object is locked for this operation.

Signed-off-by: Christian König 
---
  drivers/dma-buf/reservation.c | 56 ---
  1 file changed, 42 insertions(+), 14 deletions(-)

diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
index dec3a81..b44d9d7 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -266,8 +266,7 @@ EXPORT_SYMBOL(reservation_object_add_excl_fence);
  * @dst: the destination reservation object
  * @src: the source reservation object
  *
-* Copy all fences from src to dst. Both src->lock as well as dst-lock must be
-* held.
+* Copy all fences from src to dst. dst-lock must be held.
  */
  int reservation_object_copy_fences(struct reservation_object *dst,
   struct reservation_object *src)
@@ -277,33 +276,62 @@ int reservation_object_copy_fences(struct 
reservation_object *dst,
size_t size;
unsigned i;
  
-	src_list = reservation_object_get_list(src);

+   rcu_read_lock();
+   src_list = rcu_dereference(src->fence);
  
+retry:

if (src_list) {
-   size = offsetof(typeof(*src_list),
-   shared[src_list->shared_count]);
+   unsigned shared_count = src_list->shared_count;
+
+   size = offsetof(typeof(*src_list), shared[shared_count]);
+   rcu_read_unlock();
+
dst_list = kmalloc(size, GFP_KERNEL);
if (!dst_list)
return -ENOMEM;
  
-		dst_list->shared_count = src_list->shared_count;

-   dst_list->shared_max = src_list->shared_count;
-   for (i = 0; i < src_list->shared_count; ++i)
-   dst_list->shared[i] =
-   dma_fence_get(src_list->shared[i]);
+   rcu_read_lock();
+   src_list = rcu_dereference(src->fence);
+   if (!src_list || src_list->shared_count > shared_count) {
+   kfree(dst_list);
+   goto retry;
+   }
+
+   dst_list->shared_count = 0;
+   dst_list->shared_max = shared_count;
+   for (i = 0; i < src_list->shared_count; ++i) {
+   struct dma_fence *fence;
+
+   fence = rcu_dereference(src_list->shared[i]);
+   if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
+>flags))
+   continue;
+
+   if (!dma_fence_get_rcu(fence)) {
+   kfree(dst_list);
+   src_list = rcu_dereference(src->fence);
+   goto retry;
+   }
+
+   if (dma_fence_is_signaled(fence)) {
+   dma_fence_put(fence);
+   continue;
+   }
+
+   dst_list->shared[dst_list->shared_count++] = fence;
+   }
} else {
dst_list = NULL;
}
  
+	new = dma_fence_get_rcu_safe(>fence_excl);

+   rcu_read_unlock();
+
kfree(dst->staged);
dst->staged = NULL;
  
  	src_list = reservation_object_get_list(dst);

-
old = reservation_object_get_excl(dst);
-   new = reservation_object_get_excl(src);
-
-   dma_fence_get(new);
  
  	preempt_disable();

write_seqcount_begin(>seq);



___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/2] dma-buf: make reservation_object_copy_fences rcu save

2017-09-04 Thread Christian König
From: Christian König 

Stop requiring that the src reservation object is locked for this operation.

Signed-off-by: Christian König 
---
 drivers/dma-buf/reservation.c | 56 ---
 1 file changed, 42 insertions(+), 14 deletions(-)

diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
index dec3a81..b44d9d7 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -266,8 +266,7 @@ EXPORT_SYMBOL(reservation_object_add_excl_fence);
 * @dst: the destination reservation object
 * @src: the source reservation object
 *
-* Copy all fences from src to dst. Both src->lock as well as dst-lock must be
-* held.
+* Copy all fences from src to dst. dst-lock must be held.
 */
 int reservation_object_copy_fences(struct reservation_object *dst,
   struct reservation_object *src)
@@ -277,33 +276,62 @@ int reservation_object_copy_fences(struct 
reservation_object *dst,
size_t size;
unsigned i;
 
-   src_list = reservation_object_get_list(src);
+   rcu_read_lock();
+   src_list = rcu_dereference(src->fence);
 
+retry:
if (src_list) {
-   size = offsetof(typeof(*src_list),
-   shared[src_list->shared_count]);
+   unsigned shared_count = src_list->shared_count;
+
+   size = offsetof(typeof(*src_list), shared[shared_count]);
+   rcu_read_unlock();
+
dst_list = kmalloc(size, GFP_KERNEL);
if (!dst_list)
return -ENOMEM;
 
-   dst_list->shared_count = src_list->shared_count;
-   dst_list->shared_max = src_list->shared_count;
-   for (i = 0; i < src_list->shared_count; ++i)
-   dst_list->shared[i] =
-   dma_fence_get(src_list->shared[i]);
+   rcu_read_lock();
+   src_list = rcu_dereference(src->fence);
+   if (!src_list || src_list->shared_count > shared_count) {
+   kfree(dst_list);
+   goto retry;
+   }
+
+   dst_list->shared_count = 0;
+   dst_list->shared_max = shared_count;
+   for (i = 0; i < src_list->shared_count; ++i) {
+   struct dma_fence *fence;
+
+   fence = rcu_dereference(src_list->shared[i]);
+   if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
+>flags))
+   continue;
+
+   if (!dma_fence_get_rcu(fence)) {
+   kfree(dst_list);
+   src_list = rcu_dereference(src->fence);
+   goto retry;
+   }
+
+   if (dma_fence_is_signaled(fence)) {
+   dma_fence_put(fence);
+   continue;
+   }
+
+   dst_list->shared[dst_list->shared_count++] = fence;
+   }
} else {
dst_list = NULL;
}
 
+   new = dma_fence_get_rcu_safe(>fence_excl);
+   rcu_read_unlock();
+
kfree(dst->staged);
dst->staged = NULL;
 
src_list = reservation_object_get_list(dst);
-
old = reservation_object_get_excl(dst);
-   new = reservation_object_get_excl(src);
-
-   dma_fence_get(new);
 
preempt_disable();
write_seqcount_begin(>seq);
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel