@@ -86,34 +86,16 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv)
86
86
if (!cmdq )
87
87
return NULL ;
88
88
89
- ret = xa_alloc_cyclic (& vdev -> db_xa , & cmdq -> db_id , NULL , vdev -> db_limit , & vdev -> db_next ,
90
- GFP_KERNEL );
91
- if (ret < 0 ) {
92
- ivpu_err (vdev , "Failed to allocate doorbell id: %d\n" , ret );
93
- goto err_free_cmdq ;
94
- }
95
-
96
- ret = xa_alloc_cyclic (& file_priv -> cmdq_xa , & cmdq -> id , cmdq , file_priv -> cmdq_limit ,
97
- & file_priv -> cmdq_id_next , GFP_KERNEL );
98
- if (ret < 0 ) {
99
- ivpu_err (vdev , "Failed to allocate command queue id: %d\n" , ret );
100
- goto err_erase_db_xa ;
101
- }
102
-
103
89
cmdq -> mem = ivpu_bo_create_global (vdev , SZ_4K , DRM_IVPU_BO_WC | DRM_IVPU_BO_MAPPABLE );
104
90
if (!cmdq -> mem )
105
- goto err_erase_cmdq_xa ;
91
+ goto err_free_cmdq ;
106
92
107
93
ret = ivpu_preemption_buffers_create (vdev , file_priv , cmdq );
108
94
if (ret )
109
95
ivpu_warn (vdev , "Failed to allocate preemption buffers, preemption limited\n" );
110
96
111
97
return cmdq ;
112
98
113
- err_erase_cmdq_xa :
114
- xa_erase (& file_priv -> cmdq_xa , cmdq -> id );
115
- err_erase_db_xa :
116
- xa_erase (& vdev -> db_xa , cmdq -> db_id );
117
99
err_free_cmdq :
118
100
kfree (cmdq );
119
101
return NULL ;
@@ -231,30 +213,88 @@ static int ivpu_cmdq_fini(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cm
231
213
return 0 ;
232
214
}
233
215
216
+ static int ivpu_db_id_alloc (struct ivpu_device * vdev , u32 * db_id )
217
+ {
218
+ int ret ;
219
+ u32 id ;
220
+
221
+ ret = xa_alloc_cyclic (& vdev -> db_xa , & id , NULL , vdev -> db_limit , & vdev -> db_next , GFP_KERNEL );
222
+ if (ret < 0 )
223
+ return ret ;
224
+
225
+ * db_id = id ;
226
+ return 0 ;
227
+ }
228
+
229
+ static int ivpu_cmdq_id_alloc (struct ivpu_file_priv * file_priv , u32 * cmdq_id )
230
+ {
231
+ int ret ;
232
+ u32 id ;
233
+
234
+ ret = xa_alloc_cyclic (& file_priv -> cmdq_xa , & id , NULL , file_priv -> cmdq_limit ,
235
+ & file_priv -> cmdq_id_next , GFP_KERNEL );
236
+ if (ret < 0 )
237
+ return ret ;
238
+
239
+ * cmdq_id = id ;
240
+ return 0 ;
241
+ }
242
+
234
243
static struct ivpu_cmdq * ivpu_cmdq_acquire (struct ivpu_file_priv * file_priv , u8 priority )
235
244
{
245
+ struct ivpu_device * vdev = file_priv -> vdev ;
236
246
struct ivpu_cmdq * cmdq ;
237
- unsigned long cmdq_id ;
247
+ unsigned long id ;
238
248
int ret ;
239
249
240
250
lockdep_assert_held (& file_priv -> lock );
241
251
242
- xa_for_each (& file_priv -> cmdq_xa , cmdq_id , cmdq )
252
+ xa_for_each (& file_priv -> cmdq_xa , id , cmdq )
243
253
if (cmdq -> priority == priority )
244
254
break ;
245
255
246
256
if (!cmdq ) {
247
257
cmdq = ivpu_cmdq_alloc (file_priv );
248
- if (!cmdq )
258
+ if (!cmdq ) {
259
+ ivpu_err (vdev , "Failed to allocate command queue\n" );
249
260
return NULL ;
261
+ }
262
+
263
+ ret = ivpu_db_id_alloc (vdev , & cmdq -> db_id );
264
+ if (ret ) {
265
+ ivpu_err (file_priv -> vdev , "Failed to allocate doorbell ID: %d\n" , ret );
266
+ goto err_free_cmdq ;
267
+ }
268
+
269
+ ret = ivpu_cmdq_id_alloc (file_priv , & cmdq -> id );
270
+ if (ret ) {
271
+ ivpu_err (vdev , "Failed to allocate command queue ID: %d\n" , ret );
272
+ goto err_erase_db_id ;
273
+ }
274
+
250
275
cmdq -> priority = priority ;
276
+ ret = xa_err (xa_store (& file_priv -> cmdq_xa , cmdq -> id , cmdq , GFP_KERNEL ));
277
+ if (ret ) {
278
+ ivpu_err (vdev , "Failed to store command queue in cmdq_xa: %d\n" , ret );
279
+ goto err_erase_cmdq_id ;
280
+ }
251
281
}
252
282
253
283
ret = ivpu_cmdq_init (file_priv , cmdq , priority );
254
- if (ret )
255
- return NULL ;
284
+ if (ret ) {
285
+ ivpu_err (vdev , "Failed to initialize command queue: %d\n" , ret );
286
+ goto err_free_cmdq ;
287
+ }
256
288
257
289
return cmdq ;
290
+
291
+ err_erase_cmdq_id :
292
+ xa_erase (& file_priv -> cmdq_xa , cmdq -> id );
293
+ err_erase_db_id :
294
+ xa_erase (& vdev -> db_xa , cmdq -> db_id );
295
+ err_free_cmdq :
296
+ ivpu_cmdq_free (file_priv , cmdq );
297
+ return NULL ;
258
298
}
259
299
260
300
void ivpu_cmdq_release_all_locked (struct ivpu_file_priv * file_priv )
0 commit comments