aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2018-07-30 10:16:01 -0400
committerAlex Deucher <alexander.deucher@amd.com>2018-07-31 17:58:19 -0400
commit920990cb080a44203bf6c8eb706e79ad23241ad3 (patch)
treec561ae3c784ad5930fd2db05389b2516b89693e4
parent39f7f69a6054bb9777b47b6afdb5ce2fae30dbee (diff)
drm/amdgpu: allocate the bo_list array after the list
This avoids multiple allocations for the head and the array. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Chunming Zhou <david1.zhou@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c114
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h17
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 @@
35#define AMDGPU_BO_LIST_MAX_PRIORITY 32u 35#define AMDGPU_BO_LIST_MAX_PRIORITY 32u
36#define AMDGPU_BO_LIST_NUM_BUCKETS (AMDGPU_BO_LIST_MAX_PRIORITY + 1) 36#define AMDGPU_BO_LIST_NUM_BUCKETS (AMDGPU_BO_LIST_MAX_PRIORITY + 1)
37 37
38static int amdgpu_bo_list_set(struct amdgpu_device *adev, 38static void amdgpu_bo_list_free_rcu(struct rcu_head *rcu)
39 struct drm_file *filp, 39{
40 struct amdgpu_bo_list *list, 40 struct amdgpu_bo_list *list = container_of(rcu, struct amdgpu_bo_list,
41 struct drm_amdgpu_bo_list_entry *info, 41 rhead);
42 unsigned num_entries); 42
43 kvfree(list);
44}
43 45
44static void amdgpu_bo_list_release_rcu(struct kref *ref) 46static void amdgpu_bo_list_free(struct kref *ref)
45{ 47{
46 struct amdgpu_bo_list *list = container_of(ref, struct amdgpu_bo_list, 48 struct amdgpu_bo_list *list = container_of(ref, struct amdgpu_bo_list,
47 refcount); 49 refcount);
@@ -50,67 +52,36 @@ static void amdgpu_bo_list_release_rcu(struct kref *ref)
50 amdgpu_bo_list_for_each_entry(e, list) 52 amdgpu_bo_list_for_each_entry(e, list)
51 amdgpu_bo_unref(&e->robj); 53 amdgpu_bo_unref(&e->robj);
52 54
53 kvfree(list->array); 55 call_rcu(&list->rhead, amdgpu_bo_list_free_rcu);
54 kfree_rcu(list, rhead);
55} 56}
56 57
57int amdgpu_bo_list_create(struct amdgpu_device *adev, 58int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp,
58 struct drm_file *filp, 59 struct drm_amdgpu_bo_list_entry *info,
59 struct drm_amdgpu_bo_list_entry *info, 60 unsigned num_entries, struct amdgpu_bo_list **result)
60 unsigned num_entries,
61 struct amdgpu_bo_list **list_out)
62{ 61{
62 unsigned last_entry = 0, first_userptr = num_entries;
63 struct amdgpu_bo_list_entry *array;
63 struct amdgpu_bo_list *list; 64 struct amdgpu_bo_list *list;
65 uint64_t total_size = 0;
66 size_t size;
67 unsigned i;
64 int r; 68 int r;
65 69
70 if (num_entries > SIZE_MAX / sizeof(struct amdgpu_bo_list_entry))
71 return -EINVAL;
66 72
67 list = kzalloc(sizeof(struct amdgpu_bo_list), GFP_KERNEL); 73 size = sizeof(struct amdgpu_bo_list);
74 size += num_entries * sizeof(struct amdgpu_bo_list_entry);
75 list = kvmalloc(size, GFP_KERNEL);
68 if (!list) 76 if (!list)
69 return -ENOMEM; 77 return -ENOMEM;
70 78
71 /* initialize bo list*/
72 kref_init(&list->refcount); 79 kref_init(&list->refcount);
73 r = amdgpu_bo_list_set(adev, filp, list, info, num_entries); 80 list->gds_obj = adev->gds.gds_gfx_bo;
74 if (r) { 81 list->gws_obj = adev->gds.gws_gfx_bo;
75 kfree(list); 82 list->oa_obj = adev->gds.oa_gfx_bo;
76 return r;
77 }
78
79 *list_out = list;
80 return 0;
81}
82
83static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id)
84{
85 struct amdgpu_bo_list *list;
86
87 mutex_lock(&fpriv->bo_list_lock);
88 list = idr_remove(&fpriv->bo_list_handles, id);
89 mutex_unlock(&fpriv->bo_list_lock);
90 if (list)
91 kref_put(&list->refcount, amdgpu_bo_list_release_rcu);
92}
93
94static int amdgpu_bo_list_set(struct amdgpu_device *adev,
95 struct drm_file *filp,
96 struct amdgpu_bo_list *list,
97 struct drm_amdgpu_bo_list_entry *info,
98 unsigned num_entries)
99{
100 struct amdgpu_bo_list_entry *array;
101 struct amdgpu_bo *gds_obj = adev->gds.gds_gfx_bo;
102 struct amdgpu_bo *gws_obj = adev->gds.gws_gfx_bo;
103 struct amdgpu_bo *oa_obj = adev->gds.oa_gfx_bo;
104
105 unsigned last_entry = 0, first_userptr = num_entries;
106 struct amdgpu_bo_list_entry *e;
107 uint64_t total_size = 0;
108 unsigned i;
109 int r;
110 83
111 array = kvmalloc_array(num_entries, sizeof(struct amdgpu_bo_list_entry), GFP_KERNEL); 84 array = amdgpu_bo_list_array_entry(list, 0);
112 if (!array)
113 return -ENOMEM;
114 memset(array, 0, num_entries * sizeof(struct amdgpu_bo_list_entry)); 85 memset(array, 0, num_entries * sizeof(struct amdgpu_bo_list_entry));
115 86
116 for (i = 0; i < num_entries; ++i) { 87 for (i = 0; i < num_entries; ++i) {
@@ -147,36 +118,41 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
147 entry->tv.shared = !entry->robj->prime_shared_count; 118 entry->tv.shared = !entry->robj->prime_shared_count;
148 119
149 if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GDS) 120 if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GDS)
150 gds_obj = entry->robj; 121 list->gds_obj = entry->robj;
151 if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GWS) 122 if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GWS)
152 gws_obj = entry->robj; 123 list->gws_obj = entry->robj;
153 if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_OA) 124 if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_OA)
154 oa_obj = entry->robj; 125 list->oa_obj = entry->robj;
155 126
156 total_size += amdgpu_bo_size(entry->robj); 127 total_size += amdgpu_bo_size(entry->robj);
157 trace_amdgpu_bo_list_set(list, entry->robj); 128 trace_amdgpu_bo_list_set(list, entry->robj);
158 } 129 }
159 130
160 amdgpu_bo_list_for_each_entry(e, list)
161 amdgpu_bo_unref(&list->array[i].robj);
162
163 kvfree(list->array);
164
165 list->gds_obj = gds_obj;
166 list->gws_obj = gws_obj;
167 list->oa_obj = oa_obj;
168 list->first_userptr = first_userptr; 131 list->first_userptr = first_userptr;
169 list->array = array;
170 list->num_entries = num_entries; 132 list->num_entries = num_entries;
171 133
172 trace_amdgpu_cs_bo_status(list->num_entries, total_size); 134 trace_amdgpu_cs_bo_status(list->num_entries, total_size);
135
136 *result = list;
173 return 0; 137 return 0;
174 138
175error_free: 139error_free:
176 while (i--) 140 while (i--)
177 amdgpu_bo_unref(&array[i].robj); 141 amdgpu_bo_unref(&array[i].robj);
178 kvfree(array); 142 kvfree(list);
179 return r; 143 return r;
144
145}
146
147static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id)
148{
149 struct amdgpu_bo_list *list;
150
151 mutex_lock(&fpriv->bo_list_lock);
152 list = idr_remove(&fpriv->bo_list_handles, id);
153 mutex_unlock(&fpriv->bo_list_lock);
154 if (list)
155 kref_put(&list->refcount, amdgpu_bo_list_free);
180} 156}
181 157
182int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id, 158int 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 205
230void amdgpu_bo_list_put(struct amdgpu_bo_list *list) 206void amdgpu_bo_list_put(struct amdgpu_bo_list *list)
231{ 207{
232 kref_put(&list->refcount, amdgpu_bo_list_release_rcu); 208 kref_put(&list->refcount, amdgpu_bo_list_free);
233} 209}
234 210
235int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in, 211int 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 {
48 struct amdgpu_bo *oa_obj; 48 struct amdgpu_bo *oa_obj;
49 unsigned first_userptr; 49 unsigned first_userptr;
50 unsigned num_entries; 50 unsigned num_entries;
51 struct amdgpu_bo_list_entry *array;
52}; 51};
53 52
54int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id, 53int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
@@ -65,14 +64,22 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev,
65 unsigned num_entries, 64 unsigned num_entries,
66 struct amdgpu_bo_list **list); 65 struct amdgpu_bo_list **list);
67 66
67static inline struct amdgpu_bo_list_entry *
68amdgpu_bo_list_array_entry(struct amdgpu_bo_list *list, unsigned index)
69{
70 struct amdgpu_bo_list_entry *array = (void *)&list[1];
71
72 return &array[index];
73}
74
68#define amdgpu_bo_list_for_each_entry(e, list) \ 75#define amdgpu_bo_list_for_each_entry(e, list) \
69 for (e = &(list)->array[0]; \ 76 for (e = amdgpu_bo_list_array_entry(list, 0); \
70 e != &(list)->array[(list)->num_entries]; \ 77 e != amdgpu_bo_list_array_entry(list, (list)->num_entries); \
71 ++e) 78 ++e)
72 79
73#define amdgpu_bo_list_for_each_userptr_entry(e, list) \ 80#define amdgpu_bo_list_for_each_userptr_entry(e, list) \
74 for (e = &(list)->array[(list)->first_userptr]; \ 81 for (e = amdgpu_bo_list_array_entry(list, (list)->first_userptr); \
75 e != &(list)->array[(list)->num_entries]; \ 82 e != amdgpu_bo_list_array_entry(list, (list)->num_entries); \
76 ++e) 83 ++e)
77 84
78#endif 85#endif