2828 * Christian König <deathsimple@vodafone.de>
2929 */
3030
31+ #include <linux/sort.h>
3132#include <linux/uaccess.h>
3233
3334#include "amdgpu.h"
@@ -50,13 +51,20 @@ static void amdgpu_bo_list_free(struct kref *ref)
5051 refcount );
5152 struct amdgpu_bo_list_entry * e ;
5253
53- amdgpu_bo_list_for_each_entry (e , list ) {
54- struct amdgpu_bo * bo = ttm_to_amdgpu_bo (e -> tv .bo );
54+ amdgpu_bo_list_for_each_entry (e , list )
55+ amdgpu_bo_unref (& e -> bo );
56+ call_rcu (& list -> rhead , amdgpu_bo_list_free_rcu );
57+ }
5558
56- amdgpu_bo_unref (& bo );
57- }
59+ static int amdgpu_bo_list_entry_cmp (const void * _a , const void * _b )
60+ {
61+ const struct amdgpu_bo_list_entry * a = _a , * b = _b ;
5862
59- call_rcu (& list -> rhead , amdgpu_bo_list_free_rcu );
63+ if (a -> priority > b -> priority )
64+ return 1 ;
65+ if (a -> priority < b -> priority )
66+ return -1 ;
67+ return 0 ;
6068}
6169
6270int amdgpu_bo_list_create (struct amdgpu_device * adev , struct drm_file * filp ,
@@ -118,7 +126,7 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp,
118126
119127 entry -> priority = min (info [i ].bo_priority ,
120128 AMDGPU_BO_LIST_MAX_PRIORITY );
121- entry -> tv . bo = & bo -> tbo ;
129+ entry -> bo = bo ;
122130
123131 if (bo -> preferred_domains == AMDGPU_GEM_DOMAIN_GDS )
124132 list -> gds_obj = bo ;
@@ -133,6 +141,8 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp,
133141
134142 list -> first_userptr = first_userptr ;
135143 list -> num_entries = num_entries ;
144+ sort (array , last_entry , sizeof (struct amdgpu_bo_list_entry ),
145+ amdgpu_bo_list_entry_cmp , NULL );
136146
137147 trace_amdgpu_cs_bo_status (list -> num_entries , total_size );
138148
@@ -141,16 +151,10 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp,
141151 return 0 ;
142152
143153error_free :
144- for (i = 0 ; i < last_entry ; ++ i ) {
145- struct amdgpu_bo * bo = ttm_to_amdgpu_bo (array [i ].tv .bo );
146-
147- amdgpu_bo_unref (& bo );
148- }
149- for (i = first_userptr ; i < num_entries ; ++ i ) {
150- struct amdgpu_bo * bo = ttm_to_amdgpu_bo (array [i ].tv .bo );
151-
152- amdgpu_bo_unref (& bo );
153- }
154+ for (i = 0 ; i < last_entry ; ++ i )
155+ amdgpu_bo_unref (& array [i ].bo );
156+ for (i = first_userptr ; i < num_entries ; ++ i )
157+ amdgpu_bo_unref (& array [i ].bo );
154158 kvfree (list );
155159 return r ;
156160
@@ -182,41 +186,6 @@ int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
182186 return - ENOENT ;
183187}
184188
185- void amdgpu_bo_list_get_list (struct amdgpu_bo_list * list ,
186- struct list_head * validated )
187- {
188- /* This is based on the bucket sort with O(n) time complexity.
189- * An item with priority "i" is added to bucket[i]. The lists are then
190- * concatenated in descending order.
191- */
192- struct list_head bucket [AMDGPU_BO_LIST_NUM_BUCKETS ];
193- struct amdgpu_bo_list_entry * e ;
194- unsigned i ;
195-
196- for (i = 0 ; i < AMDGPU_BO_LIST_NUM_BUCKETS ; i ++ )
197- INIT_LIST_HEAD (& bucket [i ]);
198-
199- /* Since buffers which appear sooner in the relocation list are
200- * likely to be used more often than buffers which appear later
201- * in the list, the sort mustn't change the ordering of buffers
202- * with the same priority, i.e. it must be stable.
203- */
204- amdgpu_bo_list_for_each_entry (e , list ) {
205- struct amdgpu_bo * bo = ttm_to_amdgpu_bo (e -> tv .bo );
206- unsigned priority = e -> priority ;
207-
208- if (!bo -> parent )
209- list_add_tail (& e -> tv .head , & bucket [priority ]);
210-
211- e -> user_pages = NULL ;
212- e -> range = NULL ;
213- }
214-
215- /* Connect the sorted buckets in the output list. */
216- for (i = 0 ; i < AMDGPU_BO_LIST_NUM_BUCKETS ; i ++ )
217- list_splice (& bucket [i ], validated );
218- }
219-
220189void amdgpu_bo_list_put (struct amdgpu_bo_list * list )
221190{
222191 kref_put (& list -> refcount , amdgpu_bo_list_free );
0 commit comments