[PATCH 8/9] drm/amdgpu: allocate the bo_list array after the list

Christian König ckoenig.leichtzumerken at gmail.com
Tue Jul 31 07:04:42 UTC 2018


Am 31.07.2018 um 09:12 schrieb Huang Rui:
> On Mon, Jul 30, 2018 at 04:51:58PM +0200, Christian König wrote:
>> This avoids multiple allocations for the head and the array.
>>
> I am afraid I don't get the point that how to avoid multiple times of
> allocations. Could you please explain more?

Allocating the head and the array separately has more overhead because 
you need to do two allocations.

I should probably update the commit message,
Christian.

>
> Thanks,
> Ray
>
>> Signed-off-by: Christian König <christian.koenig at amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 114 +++++++++++-----------------
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h |  17 +++--
>>   2 files changed, 57 insertions(+), 74 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
>> index 096bcf4a6334..d472a2c8399f 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
>> @@ -35,13 +35,15 @@
>>   #define AMDGPU_BO_LIST_MAX_PRIORITY	32u
>>   #define AMDGPU_BO_LIST_NUM_BUCKETS	(AMDGPU_BO_LIST_MAX_PRIORITY + 1)
>>   
>> -static int amdgpu_bo_list_set(struct amdgpu_device *adev,
>> -				     struct drm_file *filp,
>> -				     struct amdgpu_bo_list *list,
>> -				     struct drm_amdgpu_bo_list_entry *info,
>> -				     unsigned num_entries);
>> +static void amdgpu_bo_list_free_rcu(struct rcu_head *rcu)
>> +{
>> +	struct amdgpu_bo_list *list = container_of(rcu, struct amdgpu_bo_list,
>> +						   rhead);
>> +
>> +	kvfree(list);
>> +}
>>   
>> -static void amdgpu_bo_list_release_rcu(struct kref *ref)
>> +static void amdgpu_bo_list_free(struct kref *ref)
>>   {
>>   	struct amdgpu_bo_list *list = container_of(ref, struct amdgpu_bo_list,
>>   						   refcount);
>> @@ -50,67 +52,36 @@ static void amdgpu_bo_list_release_rcu(struct kref *ref)
>>   	amdgpu_bo_list_for_each_entry(e, list)
>>   		amdgpu_bo_unref(&e->robj);
>>   
>> -	kvfree(list->array);
>> -	kfree_rcu(list, rhead);
>> +	call_rcu(&list->rhead, amdgpu_bo_list_free_rcu);
>>   }
>>   
>> -int amdgpu_bo_list_create(struct amdgpu_device *adev,
>> -				 struct drm_file *filp,
>> -				 struct drm_amdgpu_bo_list_entry *info,
>> -				 unsigned num_entries,
>> -				 struct amdgpu_bo_list **list_out)
>> +int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp,
>> +			  struct drm_amdgpu_bo_list_entry *info,
>> +			  unsigned num_entries, struct amdgpu_bo_list **result)
>>   {
>> +	unsigned last_entry = 0, first_userptr = num_entries;
>> +	struct amdgpu_bo_list_entry *array;
>>   	struct amdgpu_bo_list *list;
>> +	uint64_t total_size = 0;
>> +	size_t size;
>> +	unsigned i;
>>   	int r;
>>   
>> +	if (num_entries > SIZE_MAX / sizeof(struct amdgpu_bo_list_entry))
>> +		return -EINVAL;
>>   
>> -	list = kzalloc(sizeof(struct amdgpu_bo_list), GFP_KERNEL);
>> +	size = sizeof(struct amdgpu_bo_list);
>> +	size += num_entries * sizeof(struct amdgpu_bo_list_entry);
>> +	list = kvmalloc(size, GFP_KERNEL);
>>   	if (!list)
>>   		return -ENOMEM;
>>   
>> -	/* initialize bo list*/
>>   	kref_init(&list->refcount);
>> -	r = amdgpu_bo_list_set(adev, filp, list, info, num_entries);
>> -	if (r) {
>> -		kfree(list);
>> -		return r;
>> -	}
>> -
>> -	*list_out = list;
>> -	return 0;
>> -}
>> -
>> -static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id)
>> -{
>> -	struct amdgpu_bo_list *list;
>> -
>> -	mutex_lock(&fpriv->bo_list_lock);
>> -	list = idr_remove(&fpriv->bo_list_handles, id);
>> -	mutex_unlock(&fpriv->bo_list_lock);
>> -	if (list)
>> -		kref_put(&list->refcount, amdgpu_bo_list_release_rcu);
>> -}
>> -
>> -static int amdgpu_bo_list_set(struct amdgpu_device *adev,
>> -				     struct drm_file *filp,
>> -				     struct amdgpu_bo_list *list,
>> -				     struct drm_amdgpu_bo_list_entry *info,
>> -				     unsigned num_entries)
>> -{
>> -	struct amdgpu_bo_list_entry *array;
>> -	struct amdgpu_bo *gds_obj = adev->gds.gds_gfx_bo;
>> -	struct amdgpu_bo *gws_obj = adev->gds.gws_gfx_bo;
>> -	struct amdgpu_bo *oa_obj = adev->gds.oa_gfx_bo;
>> -
>> -	unsigned last_entry = 0, first_userptr = num_entries;
>> -	struct amdgpu_bo_list_entry *e;
>> -	uint64_t total_size = 0;
>> -	unsigned i;
>> -	int r;
>> +	list->gds_obj = adev->gds.gds_gfx_bo;
>> +	list->gws_obj = adev->gds.gws_gfx_bo;
>> +	list->oa_obj = adev->gds.oa_gfx_bo;
>>   
>> -	array = kvmalloc_array(num_entries, sizeof(struct amdgpu_bo_list_entry), GFP_KERNEL);
>> -	if (!array)
>> -		return -ENOMEM;
>> +	array = amdgpu_bo_list_array_entry(list, 0);
>>   	memset(array, 0, num_entries * sizeof(struct amdgpu_bo_list_entry));
>>   
>>   	for (i = 0; i < num_entries; ++i) {
>> @@ -147,36 +118,41 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
>>   		entry->tv.shared = !entry->robj->prime_shared_count;
>>   
>>   		if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GDS)
>> -			gds_obj = entry->robj;
>> +			list->gds_obj = entry->robj;
>>   		if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GWS)
>> -			gws_obj = entry->robj;
>> +			list->gws_obj = entry->robj;
>>   		if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_OA)
>> -			oa_obj = entry->robj;
>> +			list->oa_obj = entry->robj;
>>   
>>   		total_size += amdgpu_bo_size(entry->robj);
>>   		trace_amdgpu_bo_list_set(list, entry->robj);
>>   	}
>>   
>> -	amdgpu_bo_list_for_each_entry(e, list)
>> -		amdgpu_bo_unref(&list->array[i].robj);
>> -
>> -	kvfree(list->array);
>> -
>> -	list->gds_obj = gds_obj;
>> -	list->gws_obj = gws_obj;
>> -	list->oa_obj = oa_obj;
>>   	list->first_userptr = first_userptr;
>> -	list->array = array;
>>   	list->num_entries = num_entries;
>>   
>>   	trace_amdgpu_cs_bo_status(list->num_entries, total_size);
>> +
>> +	*result = list;
>>   	return 0;
>>   
>>   error_free:
>>   	while (i--)
>>   		amdgpu_bo_unref(&array[i].robj);
>> -	kvfree(array);
>> +	kvfree(list);
>>   	return r;
>> +
>> +}
>> +
>> +static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id)
>> +{
>> +	struct amdgpu_bo_list *list;
>> +
>> +	mutex_lock(&fpriv->bo_list_lock);
>> +	list = idr_remove(&fpriv->bo_list_handles, id);
>> +	mutex_unlock(&fpriv->bo_list_lock);
>> +	if (list)
>> +		kref_put(&list->refcount, amdgpu_bo_list_free);
>>   }
>>   
>>   int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
>> @@ -229,7 +205,7 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
>>   
>>   void amdgpu_bo_list_put(struct amdgpu_bo_list *list)
>>   {
>> -	kref_put(&list->refcount, amdgpu_bo_list_release_rcu);
>> +	kref_put(&list->refcount, amdgpu_bo_list_free);
>>   }
>>   
>>   int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in,
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
>> index 3d77abfcd4a6..61b089768e1c 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
>> @@ -48,7 +48,6 @@ struct amdgpu_bo_list {
>>   	struct amdgpu_bo *oa_obj;
>>   	unsigned first_userptr;
>>   	unsigned num_entries;
>> -	struct amdgpu_bo_list_entry *array;
>>   };
>>   
>>   int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
>> @@ -65,14 +64,22 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev,
>>   				 unsigned num_entries,
>>   				 struct amdgpu_bo_list **list);
>>   
>> +static inline struct amdgpu_bo_list_entry *
>> +amdgpu_bo_list_array_entry(struct amdgpu_bo_list *list, unsigned index)
>> +{
>> +	struct amdgpu_bo_list_entry *array = (void *)&list[1];
>> +
>> +	return &array[index];
>> +}
>> +
>>   #define amdgpu_bo_list_for_each_entry(e, list) \
>> -	for (e = &(list)->array[0]; \
>> -	     e != &(list)->array[(list)->num_entries]; \
>> +	for (e = amdgpu_bo_list_array_entry(list, 0); \
>> +	     e != amdgpu_bo_list_array_entry(list, (list)->num_entries); \
>>   	     ++e)
>>   
>>   #define amdgpu_bo_list_for_each_userptr_entry(e, list) \
>> -	for (e = &(list)->array[(list)->first_userptr]; \
>> -	     e != &(list)->array[(list)->num_entries]; \
>> +	for (e = amdgpu_bo_list_array_entry(list, (list)->first_userptr); \
>> +	     e != amdgpu_bo_list_array_entry(list, (list)->num_entries); \
>>   	     ++e)
>>   
>>   #endif
>> -- 
>> 2.14.1
>>
>> _______________________________________________
>> amd-gfx mailing list
>> amd-gfx at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx



More information about the amd-gfx mailing list