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