aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2015-12-18 15:26:47 -0500
committerAlex Deucher <alexander.deucher@amd.com>2016-02-10 14:16:47 -0500
commit636ce25c30010a8f393f5a1e67d5d4b7b66739e7 (patch)
tree64601ad38f22541bcdd264857ddb9d9c8b6959f1 /drivers/gpu/drm/amd
parent2a7d9bdabec21825ef77f5705e463342a9d7fcea (diff)
drm/amdgpu: cleanup bo list bucket handling
Move that into the BO list. No functional change. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c36
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c51
3 files changed, 39 insertions, 50 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 9c1113a96ae0..b7056649062a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1097,6 +1097,8 @@ struct amdgpu_bo_list {
1097 1097
1098struct amdgpu_bo_list * 1098struct amdgpu_bo_list *
1099amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id); 1099amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id);
1100void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
1101 struct list_head *validated);
1100void amdgpu_bo_list_put(struct amdgpu_bo_list *list); 1102void amdgpu_bo_list_put(struct amdgpu_bo_list *list);
1101void amdgpu_bo_list_free(struct amdgpu_bo_list *list); 1103void amdgpu_bo_list_free(struct amdgpu_bo_list *list);
1102 1104
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
index f82a2dd83874..9da4bd02cec3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
@@ -32,6 +32,9 @@
32#include "amdgpu.h" 32#include "amdgpu.h"
33#include "amdgpu_trace.h" 33#include "amdgpu_trace.h"
34 34
35#define AMDGPU_BO_LIST_MAX_PRIORITY 32u
36#define AMDGPU_BO_LIST_NUM_BUCKETS (AMDGPU_BO_LIST_MAX_PRIORITY + 1)
37
35static int amdgpu_bo_list_create(struct amdgpu_fpriv *fpriv, 38static int amdgpu_bo_list_create(struct amdgpu_fpriv *fpriv,
36 struct amdgpu_bo_list **result, 39 struct amdgpu_bo_list **result,
37 int *id) 40 int *id)
@@ -106,7 +109,8 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
106 109
107 entry->robj = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj)); 110 entry->robj = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj));
108 drm_gem_object_unreference_unlocked(gobj); 111 drm_gem_object_unreference_unlocked(gobj);
109 entry->priority = info[i].bo_priority; 112 entry->priority = min(info[i].bo_priority,
113 AMDGPU_BO_LIST_MAX_PRIORITY);
110 entry->prefered_domains = entry->robj->initial_domain; 114 entry->prefered_domains = entry->robj->initial_domain;
111 entry->allowed_domains = entry->prefered_domains; 115 entry->allowed_domains = entry->prefered_domains;
112 if (entry->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM) 116 if (entry->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM)
@@ -161,6 +165,36 @@ amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id)
161 return result; 165 return result;
162} 166}
163 167
168void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
169 struct list_head *validated)
170{
171 /* This is based on the bucket sort with O(n) time complexity.
172 * An item with priority "i" is added to bucket[i]. The lists are then
173 * concatenated in descending order.
174 */
175 struct list_head bucket[AMDGPU_BO_LIST_NUM_BUCKETS];
176 unsigned i;
177
178 for (i = 0; i < AMDGPU_BO_LIST_NUM_BUCKETS; i++)
179 INIT_LIST_HEAD(&bucket[i]);
180
181 /* Since buffers which appear sooner in the relocation list are
182 * likely to be used more often than buffers which appear later
183 * in the list, the sort mustn't change the ordering of buffers
184 * with the same priority, i.e. it must be stable.
185 */
186 for (i = 0; i < list->num_entries; i++) {
187 unsigned priority = list->array[i].priority;
188
189 list_add_tail(&list->array[i].tv.head,
190 &bucket[priority]);
191 }
192
193 /* Connect the sorted buckets in the output list. */
194 for (i = 0; i < AMDGPU_BO_LIST_NUM_BUCKETS; i++)
195 list_splice(&bucket[i], validated);
196}
197
164void amdgpu_bo_list_put(struct amdgpu_bo_list *list) 198void amdgpu_bo_list_put(struct amdgpu_bo_list *list)
165{ 199{
166 mutex_unlock(&list->lock); 200 mutex_unlock(&list->lock);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 5986da26a492..d249e9e0a4ea 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -30,47 +30,6 @@
30#include "amdgpu.h" 30#include "amdgpu.h"
31#include "amdgpu_trace.h" 31#include "amdgpu_trace.h"
32 32
33#define AMDGPU_CS_MAX_PRIORITY 32u
34#define AMDGPU_CS_NUM_BUCKETS (AMDGPU_CS_MAX_PRIORITY + 1)
35
36/* This is based on the bucket sort with O(n) time complexity.
37 * An item with priority "i" is added to bucket[i]. The lists are then
38 * concatenated in descending order.
39 */
40struct amdgpu_cs_buckets {
41 struct list_head bucket[AMDGPU_CS_NUM_BUCKETS];
42};
43
44static void amdgpu_cs_buckets_init(struct amdgpu_cs_buckets *b)
45{
46 unsigned i;
47
48 for (i = 0; i < AMDGPU_CS_NUM_BUCKETS; i++)
49 INIT_LIST_HEAD(&b->bucket[i]);
50}
51
52static void amdgpu_cs_buckets_add(struct amdgpu_cs_buckets *b,
53 struct list_head *item, unsigned priority)
54{
55 /* Since buffers which appear sooner in the relocation list are
56 * likely to be used more often than buffers which appear later
57 * in the list, the sort mustn't change the ordering of buffers
58 * with the same priority, i.e. it must be stable.
59 */
60 list_add_tail(item, &b->bucket[min(priority, AMDGPU_CS_MAX_PRIORITY)]);
61}
62
63static void amdgpu_cs_buckets_get_list(struct amdgpu_cs_buckets *b,
64 struct list_head *out_list)
65{
66 unsigned i;
67
68 /* Connect the sorted buckets in the output list. */
69 for (i = 0; i < AMDGPU_CS_NUM_BUCKETS; i++) {
70 list_splice(&b->bucket[i], out_list);
71 }
72}
73
74int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type, 33int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type,
75 u32 ip_instance, u32 ring, 34 u32 ip_instance, u32 ring,
76 struct amdgpu_ring **out_ring) 35 struct amdgpu_ring **out_ring)
@@ -382,22 +341,16 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
382 union drm_amdgpu_cs *cs) 341 union drm_amdgpu_cs *cs)
383{ 342{
384 struct amdgpu_fpriv *fpriv = p->filp->driver_priv; 343 struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
385 struct amdgpu_cs_buckets buckets;
386 struct list_head duplicates; 344 struct list_head duplicates;
387 bool need_mmap_lock = false; 345 bool need_mmap_lock = false;
388 int i, r; 346 int r;
389 347
390 INIT_LIST_HEAD(&p->validated); 348 INIT_LIST_HEAD(&p->validated);
391 349
392 p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle); 350 p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle);
393 if (p->bo_list) { 351 if (p->bo_list) {
394 need_mmap_lock = p->bo_list->has_userptr; 352 need_mmap_lock = p->bo_list->has_userptr;
395 amdgpu_cs_buckets_init(&buckets); 353 amdgpu_bo_list_get_list(p->bo_list, &p->validated);
396 for (i = 0; i < p->bo_list->num_entries; i++)
397 amdgpu_cs_buckets_add(&buckets, &p->bo_list->array[i].tv.head,
398 p->bo_list->array[i].priority);
399
400 amdgpu_cs_buckets_get_list(&buckets, &p->validated);
401 } 354 }
402 355
403 INIT_LIST_HEAD(&duplicates); 356 INIT_LIST_HEAD(&duplicates);