diff options
| author | Christian König <christian.koenig@amd.com> | 2015-12-18 15:26:47 -0500 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2016-02-10 14:16:47 -0500 |
| commit | 636ce25c30010a8f393f5a1e67d5d4b7b66739e7 (patch) | |
| tree | 64601ad38f22541bcdd264857ddb9d9c8b6959f1 /drivers/gpu/drm/amd/amdgpu | |
| parent | 2a7d9bdabec21825ef77f5705e463342a9d7fcea (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/amdgpu')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 36 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 51 |
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 | ||
| 1098 | struct amdgpu_bo_list * | 1098 | struct amdgpu_bo_list * |
| 1099 | amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id); | 1099 | amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id); |
| 1100 | void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list, | ||
| 1101 | struct list_head *validated); | ||
| 1100 | void amdgpu_bo_list_put(struct amdgpu_bo_list *list); | 1102 | void amdgpu_bo_list_put(struct amdgpu_bo_list *list); |
| 1101 | void amdgpu_bo_list_free(struct amdgpu_bo_list *list); | 1103 | void 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 | |||
| 35 | static int amdgpu_bo_list_create(struct amdgpu_fpriv *fpriv, | 38 | static 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 | ||
| 168 | void 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 | |||
| 164 | void amdgpu_bo_list_put(struct amdgpu_bo_list *list) | 198 | void 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 | */ | ||
| 40 | struct amdgpu_cs_buckets { | ||
| 41 | struct list_head bucket[AMDGPU_CS_NUM_BUCKETS]; | ||
| 42 | }; | ||
| 43 | |||
| 44 | static 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 | |||
| 52 | static 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 | |||
| 63 | static 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 | |||
| 74 | int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type, | 33 | int 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); |
