Commit 920990cb authored by Christian König's avatar Christian König Committed by Alex Deucher

drm/amdgpu: allocate the bo_list array after the list

This avoids multiple allocations for the head and the array.
Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarChunming  Zhou <david1.zhou@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 39f7f69a
...@@ -35,13 +35,15 @@ ...@@ -35,13 +35,15 @@
#define AMDGPU_BO_LIST_MAX_PRIORITY 32u #define AMDGPU_BO_LIST_MAX_PRIORITY 32u
#define AMDGPU_BO_LIST_NUM_BUCKETS (AMDGPU_BO_LIST_MAX_PRIORITY + 1) #define AMDGPU_BO_LIST_NUM_BUCKETS (AMDGPU_BO_LIST_MAX_PRIORITY + 1)
static int amdgpu_bo_list_set(struct amdgpu_device *adev, static void amdgpu_bo_list_free_rcu(struct rcu_head *rcu)
struct drm_file *filp, {
struct amdgpu_bo_list *list, struct amdgpu_bo_list *list = container_of(rcu, struct amdgpu_bo_list,
struct drm_amdgpu_bo_list_entry *info, rhead);
unsigned num_entries);
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, struct amdgpu_bo_list *list = container_of(ref, struct amdgpu_bo_list,
refcount); refcount);
...@@ -50,67 +52,36 @@ static void amdgpu_bo_list_release_rcu(struct kref *ref) ...@@ -50,67 +52,36 @@ static void amdgpu_bo_list_release_rcu(struct kref *ref)
amdgpu_bo_list_for_each_entry(e, list) amdgpu_bo_list_for_each_entry(e, list)
amdgpu_bo_unref(&e->robj); amdgpu_bo_unref(&e->robj);
kvfree(list->array); call_rcu(&list->rhead, amdgpu_bo_list_free_rcu);
kfree_rcu(list, rhead);
} }
int amdgpu_bo_list_create(struct amdgpu_device *adev, int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp,
struct drm_file *filp, struct drm_amdgpu_bo_list_entry *info,
struct drm_amdgpu_bo_list_entry *info, unsigned num_entries, struct amdgpu_bo_list **result)
unsigned num_entries,
struct amdgpu_bo_list **list_out)
{ {
unsigned last_entry = 0, first_userptr = num_entries;
struct amdgpu_bo_list_entry *array;
struct amdgpu_bo_list *list; struct amdgpu_bo_list *list;
uint64_t total_size = 0;
size_t size;
unsigned i;
int r; 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) if (!list)
return -ENOMEM; return -ENOMEM;
/* initialize bo list*/
kref_init(&list->refcount); kref_init(&list->refcount);
r = amdgpu_bo_list_set(adev, filp, list, info, num_entries); list->gds_obj = adev->gds.gds_gfx_bo;
if (r) { list->gws_obj = adev->gds.gws_gfx_bo;
kfree(list); list->oa_obj = adev->gds.oa_gfx_bo;
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;
array = kvmalloc_array(num_entries, sizeof(struct amdgpu_bo_list_entry), GFP_KERNEL); array = amdgpu_bo_list_array_entry(list, 0);
if (!array)
return -ENOMEM;
memset(array, 0, num_entries * sizeof(struct amdgpu_bo_list_entry)); memset(array, 0, num_entries * sizeof(struct amdgpu_bo_list_entry));
for (i = 0; i < num_entries; ++i) { for (i = 0; i < num_entries; ++i) {
...@@ -147,36 +118,41 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev, ...@@ -147,36 +118,41 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
entry->tv.shared = !entry->robj->prime_shared_count; entry->tv.shared = !entry->robj->prime_shared_count;
if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GDS) 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) 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) 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); total_size += amdgpu_bo_size(entry->robj);
trace_amdgpu_bo_list_set(list, 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->first_userptr = first_userptr;
list->array = array;
list->num_entries = num_entries; list->num_entries = num_entries;
trace_amdgpu_cs_bo_status(list->num_entries, total_size); trace_amdgpu_cs_bo_status(list->num_entries, total_size);
*result = list;
return 0; return 0;
error_free: error_free:
while (i--) while (i--)
amdgpu_bo_unref(&array[i].robj); amdgpu_bo_unref(&array[i].robj);
kvfree(array); kvfree(list);
return r; 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, 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, ...@@ -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) 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, int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in,
......
...@@ -48,7 +48,6 @@ struct amdgpu_bo_list { ...@@ -48,7 +48,6 @@ struct amdgpu_bo_list {
struct amdgpu_bo *oa_obj; struct amdgpu_bo *oa_obj;
unsigned first_userptr; unsigned first_userptr;
unsigned num_entries; unsigned num_entries;
struct amdgpu_bo_list_entry *array;
}; };
int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id, int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
...@@ -65,14 +64,22 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev, ...@@ -65,14 +64,22 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev,
unsigned num_entries, unsigned num_entries,
struct amdgpu_bo_list **list); 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) \ #define amdgpu_bo_list_for_each_entry(e, list) \
for (e = &(list)->array[0]; \ for (e = amdgpu_bo_list_array_entry(list, 0); \
e != &(list)->array[(list)->num_entries]; \ e != amdgpu_bo_list_array_entry(list, (list)->num_entries); \
++e) ++e)
#define amdgpu_bo_list_for_each_userptr_entry(e, list) \ #define amdgpu_bo_list_for_each_userptr_entry(e, list) \
for (e = &(list)->array[(list)->first_userptr]; \ for (e = amdgpu_bo_list_array_entry(list, (list)->first_userptr); \
e != &(list)->array[(list)->num_entries]; \ e != amdgpu_bo_list_array_entry(list, (list)->num_entries); \
++e) ++e)
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment