diff options
author | Christian König <christian.koenig@amd.com> | 2015-08-04 05:54:48 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2015-08-17 16:51:00 -0400 |
commit | 34cb581a7d99401cad0e1c43b528690885435f5b (patch) | |
tree | 94492c3d5633cc01deb438f03dcdbe171ee31566 | |
parent | 351dba73691fc632b269f531bbce80157f79c5b3 (diff) |
drm/amdgpu: fix bo list handling in CS
We didn't initialized the mutex in the cloned bo list resulting in nice
warnings from lockdep. Also fixes error handling in this function.
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Chunming Zhou <david1.zhou@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 83 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 5 |
3 files changed, 37 insertions, 56 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 4d6a3e825096..eadbe792c8aa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -1078,11 +1078,10 @@ struct amdgpu_bo_list { | |||
1078 | }; | 1078 | }; |
1079 | 1079 | ||
1080 | struct amdgpu_bo_list * | 1080 | struct amdgpu_bo_list * |
1081 | amdgpu_bo_list_clone(struct amdgpu_bo_list *list); | ||
1082 | struct amdgpu_bo_list * | ||
1081 | amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id); | 1083 | amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id); |
1082 | void amdgpu_bo_list_put(struct amdgpu_bo_list *list); | 1084 | void amdgpu_bo_list_put(struct amdgpu_bo_list *list); |
1083 | void amdgpu_bo_list_copy(struct amdgpu_device *adev, | ||
1084 | struct amdgpu_bo_list *dst, | ||
1085 | struct amdgpu_bo_list *src); | ||
1086 | void amdgpu_bo_list_free(struct amdgpu_bo_list *list); | 1085 | void amdgpu_bo_list_free(struct amdgpu_bo_list *list); |
1087 | 1086 | ||
1088 | /* | 1087 | /* |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index 4d27fa1660b9..7eed523bf28f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | |||
@@ -62,6 +62,39 @@ static int amdgpu_bo_list_create(struct amdgpu_fpriv *fpriv, | |||
62 | return 0; | 62 | return 0; |
63 | } | 63 | } |
64 | 64 | ||
65 | struct amdgpu_bo_list * | ||
66 | amdgpu_bo_list_clone(struct amdgpu_bo_list *list) | ||
67 | { | ||
68 | struct amdgpu_bo_list *result; | ||
69 | unsigned i; | ||
70 | |||
71 | result = kmalloc(sizeof(struct amdgpu_bo_list), GFP_KERNEL); | ||
72 | if (!result) | ||
73 | return NULL; | ||
74 | |||
75 | result->array = drm_calloc_large(list->num_entries, | ||
76 | sizeof(struct amdgpu_bo_list_entry)); | ||
77 | if (!result->array) { | ||
78 | kfree(result); | ||
79 | return NULL; | ||
80 | } | ||
81 | |||
82 | mutex_init(&result->lock); | ||
83 | result->gds_obj = list->gds_obj; | ||
84 | result->gws_obj = list->gws_obj; | ||
85 | result->oa_obj = list->oa_obj; | ||
86 | result->has_userptr = list->has_userptr; | ||
87 | result->num_entries = list->num_entries; | ||
88 | |||
89 | memcpy(result->array, list->array, list->num_entries * | ||
90 | sizeof(struct amdgpu_bo_list_entry)); | ||
91 | |||
92 | for (i = 0; i < result->num_entries; ++i) | ||
93 | amdgpu_bo_ref(result->array[i].robj); | ||
94 | |||
95 | return result; | ||
96 | } | ||
97 | |||
65 | static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id) | 98 | static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id) |
66 | { | 99 | { |
67 | struct amdgpu_bo_list *list; | 100 | struct amdgpu_bo_list *list; |
@@ -166,56 +199,6 @@ void amdgpu_bo_list_put(struct amdgpu_bo_list *list) | |||
166 | mutex_unlock(&list->lock); | 199 | mutex_unlock(&list->lock); |
167 | } | 200 | } |
168 | 201 | ||
169 | void amdgpu_bo_list_copy(struct amdgpu_device *adev, | ||
170 | struct amdgpu_bo_list *dst, | ||
171 | struct amdgpu_bo_list *src) | ||
172 | { | ||
173 | struct amdgpu_bo_list_entry *array; | ||
174 | struct amdgpu_bo *gds_obj = adev->gds.gds_gfx_bo; | ||
175 | struct amdgpu_bo *gws_obj = adev->gds.gws_gfx_bo; | ||
176 | struct amdgpu_bo *oa_obj = adev->gds.oa_gfx_bo; | ||
177 | |||
178 | bool has_userptr = false; | ||
179 | unsigned i; | ||
180 | |||
181 | array = drm_calloc_large(src->num_entries, sizeof(struct amdgpu_bo_list_entry)); | ||
182 | if (!array) | ||
183 | return; | ||
184 | memset(array, 0, src->num_entries * sizeof(struct amdgpu_bo_list_entry)); | ||
185 | |||
186 | for (i = 0; i < src->num_entries; ++i) { | ||
187 | memcpy(array, src->array, | ||
188 | src->num_entries * sizeof(struct amdgpu_bo_list_entry)); | ||
189 | array[i].robj = amdgpu_bo_ref(src->array[i].robj); | ||
190 | if (amdgpu_ttm_tt_has_userptr(array[i].robj->tbo.ttm)) { | ||
191 | has_userptr = true; | ||
192 | array[i].prefered_domains = AMDGPU_GEM_DOMAIN_GTT; | ||
193 | array[i].allowed_domains = AMDGPU_GEM_DOMAIN_GTT; | ||
194 | } | ||
195 | array[i].tv.bo = &array[i].robj->tbo; | ||
196 | array[i].tv.shared = true; | ||
197 | |||
198 | if (array[i].prefered_domains == AMDGPU_GEM_DOMAIN_GDS) | ||
199 | gds_obj = array[i].robj; | ||
200 | if (array[i].prefered_domains == AMDGPU_GEM_DOMAIN_GWS) | ||
201 | gws_obj = array[i].robj; | ||
202 | if (array[i].prefered_domains == AMDGPU_GEM_DOMAIN_OA) | ||
203 | oa_obj = array[i].robj; | ||
204 | } | ||
205 | |||
206 | for (i = 0; i < dst->num_entries; ++i) | ||
207 | amdgpu_bo_unref(&dst->array[i].robj); | ||
208 | |||
209 | drm_free_large(dst->array); | ||
210 | |||
211 | dst->gds_obj = gds_obj; | ||
212 | dst->gws_obj = gws_obj; | ||
213 | dst->oa_obj = oa_obj; | ||
214 | dst->has_userptr = has_userptr; | ||
215 | dst->array = array; | ||
216 | dst->num_entries = src->num_entries; | ||
217 | } | ||
218 | |||
219 | void amdgpu_bo_list_free(struct amdgpu_bo_list *list) | 202 | void amdgpu_bo_list_free(struct amdgpu_bo_list *list) |
220 | { | 203 | { |
221 | unsigned i; | 204 | unsigned i; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index d4cc232ccff3..aa1bc24b7edb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
@@ -186,11 +186,10 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) | |||
186 | } | 186 | } |
187 | bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle); | 187 | bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle); |
188 | if (bo_list && !bo_list->has_userptr) { | 188 | if (bo_list && !bo_list->has_userptr) { |
189 | p->bo_list = kzalloc(sizeof(struct amdgpu_bo_list), GFP_KERNEL); | 189 | p->bo_list = amdgpu_bo_list_clone(bo_list); |
190 | amdgpu_bo_list_put(bo_list); | ||
190 | if (!p->bo_list) | 191 | if (!p->bo_list) |
191 | return -ENOMEM; | 192 | return -ENOMEM; |
192 | amdgpu_bo_list_copy(p->adev, p->bo_list, bo_list); | ||
193 | amdgpu_bo_list_put(bo_list); | ||
194 | } else if (bo_list && bo_list->has_userptr) | 193 | } else if (bo_list && bo_list->has_userptr) |
195 | p->bo_list = bo_list; | 194 | p->bo_list = bo_list; |
196 | else | 195 | else |