23
23
24
24
/* make sure these don't conflict w/ MSM_SUBMIT_BO_x */
25
25
#define BO_VALID 0x8000 /* is current addr in cmdstream correct/valid? */
26
- #define BO_LOCKED 0x4000
27
- #define BO_PINNED 0x2000
26
+ #define BO_LOCKED 0x4000 /* obj lock is held */
27
+ #define BO_PINNED 0x2000 /* obj is pinned and on active list */
28
28
29
29
static struct msm_gem_submit * submit_create (struct drm_device * dev ,
30
30
struct msm_gpu * gpu ,
@@ -220,21 +220,33 @@ static int submit_lookup_cmds(struct msm_gem_submit *submit,
220
220
return ret ;
221
221
}
222
222
223
- static void submit_unlock_unpin_bo (struct msm_gem_submit * submit ,
224
- int i , bool backoff )
223
+ /* Unwind bo state, according to cleanup_flags. In the success case, only
224
+ * the lock is dropped at the end of the submit (and active/pin ref is dropped
225
+ * later when the submit is retired).
226
+ */
227
+ static void submit_cleanup_bo (struct msm_gem_submit * submit , int i ,
228
+ unsigned cleanup_flags )
225
229
{
226
- struct msm_gem_object * msm_obj = submit -> bos [i ].obj ;
230
+ struct drm_gem_object * obj = & submit -> bos [i ].obj -> base ;
231
+ unsigned flags = submit -> bos [i ].flags & cleanup_flags ;
227
232
228
- if (submit -> bos [i ].flags & BO_PINNED )
229
- msm_gem_unpin_iova_locked (& msm_obj -> base , submit -> aspace );
233
+ if (flags & BO_PINNED ) {
234
+ msm_gem_unpin_iova_locked (obj , submit -> aspace );
235
+ msm_gem_active_put (obj );
236
+ }
230
237
231
- if (submit -> bos [ i ]. flags & BO_LOCKED )
232
- dma_resv_unlock (msm_obj -> base . resv );
238
+ if (flags & BO_LOCKED )
239
+ dma_resv_unlock (obj -> resv );
233
240
234
- if ( backoff && !( submit -> bos [i ].flags & BO_VALID ))
235
- submit -> bos [ i ]. iova = 0 ;
241
+ submit -> bos [i ].flags &= ~ cleanup_flags ;
242
+ }
236
243
237
- submit -> bos [i ].flags &= ~(BO_LOCKED | BO_PINNED );
244
+ static void submit_unlock_unpin_bo (struct msm_gem_submit * submit , int i )
245
+ {
246
+ submit_cleanup_bo (submit , i , BO_PINNED | BO_LOCKED );
247
+
248
+ if (!(submit -> bos [i ].flags & BO_VALID ))
249
+ submit -> bos [i ].iova = 0 ;
238
250
}
239
251
240
252
/* This is where we make sure all the bo's are reserved and pin'd: */
@@ -266,10 +278,10 @@ static int submit_lock_objects(struct msm_gem_submit *submit)
266
278
267
279
fail :
268
280
for (; i >= 0 ; i -- )
269
- submit_unlock_unpin_bo (submit , i , true );
281
+ submit_unlock_unpin_bo (submit , i );
270
282
271
283
if (slow_locked > 0 )
272
- submit_unlock_unpin_bo (submit , slow_locked , true );
284
+ submit_unlock_unpin_bo (submit , slow_locked );
273
285
274
286
if (ret == - EDEADLK ) {
275
287
struct msm_gem_object * msm_obj = submit -> bos [contended ].obj ;
@@ -325,16 +337,18 @@ static int submit_pin_objects(struct msm_gem_submit *submit)
325
337
submit -> valid = true;
326
338
327
339
for (i = 0 ; i < submit -> nr_bos ; i ++ ) {
328
- struct msm_gem_object * msm_obj = submit -> bos [i ].obj ;
340
+ struct drm_gem_object * obj = & submit -> bos [i ].obj -> base ;
329
341
uint64_t iova ;
330
342
331
343
/* if locking succeeded, pin bo: */
332
- ret = msm_gem_get_and_pin_iova_locked (& msm_obj -> base ,
344
+ ret = msm_gem_get_and_pin_iova_locked (obj ,
333
345
submit -> aspace , & iova );
334
346
335
347
if (ret )
336
348
break ;
337
349
350
+ msm_gem_active_get (obj , submit -> gpu );
351
+
338
352
submit -> bos [i ].flags |= BO_PINNED ;
339
353
340
354
if (iova == submit -> bos [i ].iova ) {
@@ -350,6 +364,20 @@ static int submit_pin_objects(struct msm_gem_submit *submit)
350
364
return ret ;
351
365
}
352
366
367
+ static void submit_attach_object_fences (struct msm_gem_submit * submit )
368
+ {
369
+ int i ;
370
+
371
+ for (i = 0 ; i < submit -> nr_bos ; i ++ ) {
372
+ struct drm_gem_object * obj = & submit -> bos [i ].obj -> base ;
373
+
374
+ if (submit -> bos [i ].flags & MSM_SUBMIT_BO_WRITE )
375
+ dma_resv_add_excl_fence (obj -> resv , submit -> fence );
376
+ else if (submit -> bos [i ].flags & MSM_SUBMIT_BO_READ )
377
+ dma_resv_add_shared_fence (obj -> resv , submit -> fence );
378
+ }
379
+ }
380
+
353
381
static int submit_bo (struct msm_gem_submit * submit , uint32_t idx ,
354
382
struct msm_gem_object * * obj , uint64_t * iova , bool * valid )
355
383
{
@@ -444,18 +472,40 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob
444
472
return ret ;
445
473
}
446
474
447
- static void submit_cleanup (struct msm_gem_submit * submit )
475
+ /* Cleanup submit at end of ioctl. In the error case, this also drops
476
+ * references, unpins, and drops active refcnt. In the non-error case,
477
+ * this is done when the submit is retired.
478
+ */
479
+ static void submit_cleanup (struct msm_gem_submit * submit , bool error )
448
480
{
481
+ unsigned cleanup_flags = BO_LOCKED ;
449
482
unsigned i ;
450
483
484
+ if (error )
485
+ cleanup_flags |= BO_PINNED ;
486
+
451
487
for (i = 0 ; i < submit -> nr_bos ; i ++ ) {
452
488
struct msm_gem_object * msm_obj = submit -> bos [i ].obj ;
453
- submit_unlock_unpin_bo (submit , i , false );
489
+ submit_cleanup_bo (submit , i , cleanup_flags );
454
490
list_del_init (& msm_obj -> submit_entry );
455
- drm_gem_object_put (& msm_obj -> base );
491
+ if (error )
492
+ drm_gem_object_put (& msm_obj -> base );
456
493
}
457
494
}
458
495
496
+ void msm_submit_retire (struct msm_gem_submit * submit )
497
+ {
498
+ int i ;
499
+
500
+ for (i = 0 ; i < submit -> nr_bos ; i ++ ) {
501
+ struct drm_gem_object * obj = & submit -> bos [i ].obj -> base ;
502
+
503
+ msm_gem_lock (obj );
504
+ submit_cleanup_bo (submit , i , BO_PINNED );
505
+ msm_gem_unlock (obj );
506
+ drm_gem_object_put (obj );
507
+ }
508
+ }
459
509
460
510
struct msm_submit_post_dep {
461
511
struct drm_syncobj * syncobj ;
@@ -832,6 +882,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
832
882
args -> fence_fd = out_fence_fd ;
833
883
}
834
884
885
+ submit_attach_object_fences (submit );
886
+
835
887
msm_gpu_submit (gpu , submit );
836
888
837
889
args -> fence = submit -> fence -> seqno ;
@@ -844,7 +896,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
844
896
out :
845
897
pm_runtime_put (& gpu -> pdev -> dev );
846
898
out_pre_pm :
847
- submit_cleanup (submit );
899
+ submit_cleanup (submit , !! ret );
848
900
if (has_ww_ticket )
849
901
ww_acquire_fini (& submit -> ticket );
850
902
msm_gem_submit_put (submit );
0 commit comments