diff mbox series

[1/2] dma-buf: Expand reservation_list to fill allocation

Message ID 20190712080314.21018-1-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show
Series [1/2] dma-buf: Expand reservation_list to fill allocation | expand

Commit Message

Chris Wilson July 12, 2019, 8:03 a.m. UTC
Since kmalloc() will round up the allocation to the next slab size or
page, it will normally return a pointer to a memory block bigger than we
asked for. We can query for the actual size of the allocated block using
ksize() and expand our variable size reservation_list to take advantage
of that extra space.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Christian König <christian.koenig@amd.com>
Cc: Michel Dänzer <michel.daenzer@amd.com>
---
 drivers/dma-buf/reservation.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Comments

Michel Dänzer July 12, 2019, 8:33 a.m. UTC | #1
On 2019-07-12 10:03 a.m., Chris Wilson wrote:
> Since kmalloc() will round up the allocation to the next slab size or
> page, it will normally return a pointer to a memory block bigger than we
> asked for. We can query for the actual size of the allocated block using
> ksize() and expand our variable size reservation_list to take advantage
> of that extra space.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Michel Dänzer <michel.daenzer@amd.com>
> ---
>  drivers/dma-buf/reservation.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
> index a6ac2b3a0185..80ecc1283d15 100644
> --- a/drivers/dma-buf/reservation.c
> +++ b/drivers/dma-buf/reservation.c
> @@ -153,7 +153,9 @@ int reservation_object_reserve_shared(struct reservation_object *obj,
>  			RCU_INIT_POINTER(new->shared[j++], fence);
>  	}
>  	new->shared_count = j;
> -	new->shared_max = max;
> +	new->shared_max =
> +		(ksize(new) - offsetof(typeof(*new), shared)) /
> +		sizeof(*new->shared);
>  
>  	preempt_disable();
>  	write_seqcount_begin(&obj->seq);
> @@ -169,7 +171,7 @@ int reservation_object_reserve_shared(struct reservation_object *obj,
>  		return 0;
>  
>  	/* Drop the references to the signaled fences */
> -	for (i = k; i < new->shared_max; ++i) {
> +	for (i = k; i < max; ++i) {
>  		struct dma_fence *fence;
>  
>  		fence = rcu_dereference_protected(new->shared[i],
> 

Nice, TIL about ksize(), wonder where else that could be used.

Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>


P.S. According to scripts/get_maintainer.pl , this series should be sent
to more recipients for review.
Christian König July 14, 2019, 7:37 a.m. UTC | #2
Am 12.07.19 um 10:03 schrieb Chris Wilson:
> Since kmalloc() will round up the allocation to the next slab size or
> page, it will normally return a pointer to a memory block bigger than we
> asked for. We can query for the actual size of the allocated block using
> ksize() and expand our variable size reservation_list to take advantage
> of that extra space.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Michel Dänzer <michel.daenzer@amd.com>

Reviewed-by: Christian König <christian.koenig@amd.com>

BTW: I was wondering if we shouldn't replace the reservation_object_list 
with a dma_fence_chain.

That would costs us a bit more memory and is slightly slower on querying 
the fence in the container.

But it would be much faster on adding new fences and massively 
simplifies waiting or returning all fences currently in the container.

Christian.

> ---
>   drivers/dma-buf/reservation.c | 6 ++++--
>   1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
> index a6ac2b3a0185..80ecc1283d15 100644
> --- a/drivers/dma-buf/reservation.c
> +++ b/drivers/dma-buf/reservation.c
> @@ -153,7 +153,9 @@ int reservation_object_reserve_shared(struct reservation_object *obj,
>   			RCU_INIT_POINTER(new->shared[j++], fence);
>   	}
>   	new->shared_count = j;
> -	new->shared_max = max;
> +	new->shared_max =
> +		(ksize(new) - offsetof(typeof(*new), shared)) /
> +		sizeof(*new->shared);
>   
>   	preempt_disable();
>   	write_seqcount_begin(&obj->seq);
> @@ -169,7 +171,7 @@ int reservation_object_reserve_shared(struct reservation_object *obj,
>   		return 0;
>   
>   	/* Drop the references to the signaled fences */
> -	for (i = k; i < new->shared_max; ++i) {
> +	for (i = k; i < max; ++i) {
>   		struct dma_fence *fence;
>   
>   		fence = rcu_dereference_protected(new->shared[i],
Chris Wilson July 15, 2019, 10:58 a.m. UTC | #3
Quoting Koenig, Christian (2019-07-14 08:37:47)
> Am 12.07.19 um 10:03 schrieb Chris Wilson:
> > Since kmalloc() will round up the allocation to the next slab size or
> > page, it will normally return a pointer to a memory block bigger than we
> > asked for. We can query for the actual size of the allocated block using
> > ksize() and expand our variable size reservation_list to take advantage
> > of that extra space.
> >
> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> > Cc: Christian König <christian.koenig@amd.com>
> > Cc: Michel Dänzer <michel.daenzer@amd.com>
> 
> Reviewed-by: Christian König <christian.koenig@amd.com>
> 
> BTW: I was wondering if we shouldn't replace the reservation_object_list 
> with a dma_fence_chain.

I thought the dma_fence_chain tracked points (naturally ordered) along a
singe timeline, whereas the reservation list tracked parallel timelines.
Seems like a semantic mismatch?

(Making lookup slower would not be pleasant, tbh, both waiting on and
updating are an issue with the severe amount of reservation_objects we
currently process per execbuf.)
-Chris
Chris Wilson July 15, 2019, 11:11 a.m. UTC | #4
Quoting Chris Wilson (2019-07-12 09:03:13)
> Since kmalloc() will round up the allocation to the next slab size or
> page, it will normally return a pointer to a memory block bigger than we
> asked for. We can query for the actual size of the allocated block using
> ksize() and expand our variable size reservation_list to take advantage
> of that extra space.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Michel Dänzer <michel.daenzer@amd.com>

Pushed to drm-misc-next, thanks for the reviews!

Anyone feel brave enough for the second? :)
-Chris
diff mbox series

Patch

diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
index a6ac2b3a0185..80ecc1283d15 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -153,7 +153,9 @@  int reservation_object_reserve_shared(struct reservation_object *obj,
 			RCU_INIT_POINTER(new->shared[j++], fence);
 	}
 	new->shared_count = j;
-	new->shared_max = max;
+	new->shared_max =
+		(ksize(new) - offsetof(typeof(*new), shared)) /
+		sizeof(*new->shared);
 
 	preempt_disable();
 	write_seqcount_begin(&obj->seq);
@@ -169,7 +171,7 @@  int reservation_object_reserve_shared(struct reservation_object *obj,
 		return 0;
 
 	/* Drop the references to the signaled fences */
-	for (i = k; i < new->shared_max; ++i) {
+	for (i = k; i < max; ++i) {
 		struct dma_fence *fence;
 
 		fence = rcu_dereference_protected(new->shared[i],