@@ -83,34 +83,16 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv)
8383 if (!cmdq )
8484 return NULL ;
8585
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-
10086 cmdq -> mem = ivpu_bo_create_global (vdev , SZ_4K , DRM_IVPU_BO_WC | DRM_IVPU_BO_MAPPABLE );
10187 if (!cmdq -> mem )
102- goto err_erase_cmdq_xa ;
88+ goto err_free_cmdq ;
10389
10490 ret = ivpu_preemption_buffers_create (vdev , file_priv , cmdq );
10591 if (ret )
10692 ivpu_warn (vdev , "Failed to allocate preemption buffers, preemption limited\n" );
10793
10894 return cmdq ;
10995
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 );
11496err_free_cmdq :
11597 kfree (cmdq );
11698 return NULL ;
@@ -233,30 +215,88 @@ static int ivpu_cmdq_fini(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cm
233215 return 0 ;
234216}
235217
218+ static int ivpu_db_id_alloc (struct ivpu_device * vdev , u32 * db_id )
219+ {
220+ int ret ;
221+ u32 id ;
222+
223+ ret = xa_alloc_cyclic (& vdev -> db_xa , & id , NULL , vdev -> db_limit , & vdev -> db_next , GFP_KERNEL );
224+ if (ret < 0 )
225+ return ret ;
226+
227+ * db_id = id ;
228+ return 0 ;
229+ }
230+
231+ static int ivpu_cmdq_id_alloc (struct ivpu_file_priv * file_priv , u32 * cmdq_id )
232+ {
233+ int ret ;
234+ u32 id ;
235+
236+ ret = xa_alloc_cyclic (& file_priv -> cmdq_xa , & id , NULL , file_priv -> cmdq_limit ,
237+ & file_priv -> cmdq_id_next , GFP_KERNEL );
238+ if (ret < 0 )
239+ return ret ;
240+
241+ * cmdq_id = id ;
242+ return 0 ;
243+ }
244+
236245static struct ivpu_cmdq * ivpu_cmdq_acquire (struct ivpu_file_priv * file_priv , u8 priority )
237246{
247+ struct ivpu_device * vdev = file_priv -> vdev ;
238248 struct ivpu_cmdq * cmdq ;
239- unsigned long cmdq_id ;
249+ unsigned long id ;
240250 int ret ;
241251
242252 lockdep_assert_held (& file_priv -> lock );
243253
244- xa_for_each (& file_priv -> cmdq_xa , cmdq_id , cmdq )
254+ xa_for_each (& file_priv -> cmdq_xa , id , cmdq )
245255 if (cmdq -> priority == priority )
246256 break ;
247257
248258 if (!cmdq ) {
249259 cmdq = ivpu_cmdq_alloc (file_priv );
250- if (!cmdq )
260+ if (!cmdq ) {
261+ ivpu_err (vdev , "Failed to allocate command queue\n" );
251262 return NULL ;
263+ }
264+
265+ ret = ivpu_db_id_alloc (vdev , & cmdq -> db_id );
266+ if (ret ) {
267+ ivpu_err (file_priv -> vdev , "Failed to allocate doorbell ID: %d\n" , ret );
268+ goto err_free_cmdq ;
269+ }
270+
271+ ret = ivpu_cmdq_id_alloc (file_priv , & cmdq -> id );
272+ if (ret ) {
273+ ivpu_err (vdev , "Failed to allocate command queue ID: %d\n" , ret );
274+ goto err_erase_db_id ;
275+ }
276+
252277 cmdq -> priority = priority ;
278+ ret = xa_err (xa_store (& file_priv -> cmdq_xa , cmdq -> id , cmdq , GFP_KERNEL ));
279+ if (ret ) {
280+ ivpu_err (vdev , "Failed to store command queue in cmdq_xa: %d\n" , ret );
281+ goto err_erase_cmdq_id ;
282+ }
253283 }
254284
255285 ret = ivpu_cmdq_init (file_priv , cmdq , priority );
256- if (ret )
257- return NULL ;
286+ if (ret ) {
287+ ivpu_err (vdev , "Failed to initialize command queue: %d\n" , ret );
288+ goto err_free_cmdq ;
289+ }
258290
259291 return cmdq ;
292+
293+ err_erase_cmdq_id :
294+ xa_erase (& file_priv -> cmdq_xa , cmdq -> id );
295+ err_erase_db_id :
296+ xa_erase (& vdev -> db_xa , cmdq -> db_id );
297+ err_free_cmdq :
298+ ivpu_cmdq_free (file_priv , cmdq );
299+ return NULL ;
260300}
261301
262302void ivpu_cmdq_release_all_locked (struct ivpu_file_priv * file_priv )
0 commit comments