aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
diff options
context:
space:
mode:
authorAndrey Grodzovsky <andrey.grodzovsky@amd.com>2018-07-06 14:16:54 -0400
committerAlex Deucher <alexander.deucher@amd.com>2018-07-16 16:29:47 -0400
commit964d0fbf6301d3dc8dfad19ffab5a06d002d27f1 (patch)
treeb158d245de63e888bf20897b8f8cecb7fb6cede1 /drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
parent8415afbd86ddd8a268a8450286bc58b2bb3b83d1 (diff)
drm/amdgpu: Allow to create BO lists in CS ioctl v3
This change is to support MESA performace optimization. Modify CS IOCTL to allow its input as command buffer and an array of buffer handles to create a temporay bo list and then destroy it when IOCTL completes. This saves on calling for BO_LIST create and destry IOCTLs in MESA and by this improves performance. v2: Avoid inserting the temp list into idr struct. v3: Remove idr alloation from amdgpu_bo_list_create. Remove useless argument from amdgpu_cs_parser_fini Minor cosmetic stuff. v4: Revert amdgpu_bo_list_destroy back to static Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@amd.com> Reviewed-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>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 5a2a5ba29f9a..6d8df76b5a5d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -66,11 +66,35 @@ static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p,
66 return 0; 66 return 0;
67} 67}
68 68
69static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) 69static int amdgpu_cs_bo_handles_chunk(struct amdgpu_cs_parser *p,
70 struct drm_amdgpu_bo_list_in *data)
71{
72 int r;
73 struct drm_amdgpu_bo_list_entry *info = NULL;
74
75 r = amdgpu_bo_create_list_entry_array(data, &info);
76 if (r)
77 return r;
78
79 r = amdgpu_bo_list_create(p->adev, p->filp, info, data->bo_number,
80 &p->bo_list);
81 if (r)
82 goto error_free;
83
84 kvfree(info);
85 return 0;
86
87error_free:
88 if (info)
89 kvfree(info);
90
91 return r;
92}
93
94static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs *cs)
70{ 95{
71 struct amdgpu_fpriv *fpriv = p->filp->driver_priv; 96 struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
72 struct amdgpu_vm *vm = &fpriv->vm; 97 struct amdgpu_vm *vm = &fpriv->vm;
73 union drm_amdgpu_cs *cs = data;
74 uint64_t *chunk_array_user; 98 uint64_t *chunk_array_user;
75 uint64_t *chunk_array; 99 uint64_t *chunk_array;
76 unsigned size, num_ibs = 0; 100 unsigned size, num_ibs = 0;
@@ -164,6 +188,19 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
164 188
165 break; 189 break;
166 190
191 case AMDGPU_CHUNK_ID_BO_HANDLES:
192 size = sizeof(struct drm_amdgpu_bo_list_in);
193 if (p->chunks[i].length_dw * sizeof(uint32_t) < size) {
194 ret = -EINVAL;
195 goto free_partial_kdata;
196 }
197
198 ret = amdgpu_cs_bo_handles_chunk(p, p->chunks[i].kdata);
199 if (ret)
200 goto free_partial_kdata;
201
202 break;
203
167 case AMDGPU_CHUNK_ID_DEPENDENCIES: 204 case AMDGPU_CHUNK_ID_DEPENDENCIES:
168 case AMDGPU_CHUNK_ID_SYNCOBJ_IN: 205 case AMDGPU_CHUNK_ID_SYNCOBJ_IN:
169 case AMDGPU_CHUNK_ID_SYNCOBJ_OUT: 206 case AMDGPU_CHUNK_ID_SYNCOBJ_OUT:
@@ -534,7 +571,12 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
534 571
535 INIT_LIST_HEAD(&p->validated); 572 INIT_LIST_HEAD(&p->validated);
536 573
537 p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle); 574 /* p->bo_list could already be assigned if AMDGPU_CHUNK_ID_BO_HANDLES is present */
575 if (!p->bo_list)
576 p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle);
577 else
578 mutex_lock(&p->bo_list->lock);
579
538 if (p->bo_list) { 580 if (p->bo_list) {
539 amdgpu_bo_list_get_list(p->bo_list, &p->validated); 581 amdgpu_bo_list_get_list(p->bo_list, &p->validated);
540 if (p->bo_list->first_userptr != p->bo_list->num_entries) 582 if (p->bo_list->first_userptr != p->bo_list->num_entries)