3
3
* Copyright © 2021 Intel Corporation
4
4
*/
5
5
6
- #include <linux/dma-fence-array.h>
7
-
8
6
#include <drm/ttm/ttm_bo_driver.h>
9
7
10
8
#include "i915_drv.h"
@@ -44,17 +42,12 @@ void i915_ttm_migrate_set_failure_modes(bool gpu_migration,
44
42
#endif
45
43
46
44
/**
47
- * DOC: Set of utilities to dynamically collect dependencies and
48
- * eventually coalesce them into a single fence which is fed into
49
- * the GT migration code, since it only accepts a single dependency
50
- * fence.
51
- * The single fence returned from these utilities, in the case of
52
- * dependencies from multiple fence contexts, a struct dma_fence_array,
53
- * since the i915 request code can break that up and await the individual
54
- * fences.
45
+ * DOC: Set of utilities to dynamically collect dependencies into a
46
+ * structure which is fed into the GT migration code.
55
47
*
56
48
* Once we can do async unbinding, this is also needed to coalesce
57
- * the migration fence with the unbind fences.
49
+ * the migration fence with the unbind fences if these are coalesced
50
+ * post-migration.
58
51
*
59
52
* While collecting the individual dependencies, we store the refcounted
60
53
* struct dma_fence pointers in a realloc-managed pointer array, since
@@ -65,32 +58,13 @@ void i915_ttm_migrate_set_failure_modes(bool gpu_migration,
65
58
* A struct i915_deps need to be initialized using i915_deps_init().
66
59
* If i915_deps_add_dependency() or i915_deps_add_resv() return an
67
60
* error code they will internally call i915_deps_fini(), which frees
68
- * all internal references and allocations. After a call to
69
- * i915_deps_to_fence(), or i915_deps_sync(), the struct should similarly
70
- * be viewed as uninitialized.
61
+ * all internal references and allocations.
71
62
*
72
63
* We might want to break this out into a separate file as a utility.
73
64
*/
74
65
75
66
#define I915_DEPS_MIN_ALLOC_CHUNK 8U
76
67
77
- /**
78
- * struct i915_deps - Collect dependencies into a single dma-fence
79
- * @single: Storage for pointer if the collection is a single fence.
80
- * @fence: Allocated array of fence pointers if more than a single fence;
81
- * otherwise points to the address of @single.
82
- * @num_deps: Current number of dependency fences.
83
- * @fences_size: Size of the @fences array in number of pointers.
84
- * @gfp: Allocation mode.
85
- */
86
- struct i915_deps {
87
- struct dma_fence * single ;
88
- struct dma_fence * * fences ;
89
- unsigned int num_deps ;
90
- unsigned int fences_size ;
91
- gfp_t gfp ;
92
- };
93
-
94
68
static void i915_deps_reset_fences (struct i915_deps * deps )
95
69
{
96
70
if (deps -> fences != & deps -> single )
@@ -163,7 +137,7 @@ static int i915_deps_grow(struct i915_deps *deps, struct dma_fence *fence,
163
137
return ret ;
164
138
}
165
139
166
- static int i915_deps_sync (struct i915_deps * deps ,
140
+ static int i915_deps_sync (const struct i915_deps * deps ,
167
141
const struct ttm_operation_ctx * ctx )
168
142
{
169
143
struct dma_fence * * fences = deps -> fences ;
@@ -183,7 +157,6 @@ static int i915_deps_sync(struct i915_deps *deps,
183
157
break ;
184
158
}
185
159
186
- i915_deps_fini (deps );
187
160
return ret ;
188
161
}
189
162
@@ -221,34 +194,6 @@ static int i915_deps_add_dependency(struct i915_deps *deps,
221
194
return i915_deps_grow (deps , fence , ctx );
222
195
}
223
196
224
- static struct dma_fence * i915_deps_to_fence (struct i915_deps * deps ,
225
- const struct ttm_operation_ctx * ctx )
226
- {
227
- struct dma_fence_array * array ;
228
-
229
- if (deps -> num_deps == 0 )
230
- return NULL ;
231
-
232
- if (deps -> num_deps == 1 ) {
233
- deps -> num_deps = 0 ;
234
- return deps -> fences [0 ];
235
- }
236
-
237
- /*
238
- * TODO: Alter the allocation mode here to not try too hard to
239
- * make things async.
240
- */
241
- array = dma_fence_array_create (deps -> num_deps , deps -> fences , 0 , 0 ,
242
- false);
243
- if (!array )
244
- return ERR_PTR (i915_deps_sync (deps , ctx ));
245
-
246
- deps -> fences = NULL ;
247
- i915_deps_reset_fences (deps );
248
-
249
- return & array -> base ;
250
- }
251
-
252
197
static int i915_deps_add_resv (struct i915_deps * deps , struct dma_resv * resv ,
253
198
bool all , const bool no_excl ,
254
199
const struct ttm_operation_ctx * ctx )
@@ -387,7 +332,7 @@ static struct dma_fence *i915_ttm_accel_move(struct ttm_buffer_object *bo,
387
332
struct ttm_resource * dst_mem ,
388
333
struct ttm_tt * dst_ttm ,
389
334
struct sg_table * dst_st ,
390
- struct dma_fence * dep )
335
+ const struct i915_deps * deps )
391
336
{
392
337
struct drm_i915_private * i915 = container_of (bo -> bdev , typeof (* i915 ),
393
338
bdev );
@@ -411,7 +356,7 @@ static struct dma_fence *i915_ttm_accel_move(struct ttm_buffer_object *bo,
411
356
return ERR_PTR (- EINVAL );
412
357
413
358
intel_engine_pm_get (to_gt (i915 )-> migrate .context -> engine );
414
- ret = intel_context_migrate_clear (to_gt (i915 )-> migrate .context , dep ,
359
+ ret = intel_context_migrate_clear (to_gt (i915 )-> migrate .context , deps ,
415
360
dst_st -> sgl , dst_level ,
416
361
i915_ttm_gtt_binds_lmem (dst_mem ),
417
362
0 , & rq );
@@ -425,7 +370,7 @@ static struct dma_fence *i915_ttm_accel_move(struct ttm_buffer_object *bo,
425
370
src_level = i915_ttm_cache_level (i915 , bo -> resource , src_ttm );
426
371
intel_engine_pm_get (to_gt (i915 )-> migrate .context -> engine );
427
372
ret = intel_context_migrate_copy (to_gt (i915 )-> migrate .context ,
428
- dep , src_rsgt -> table .sgl ,
373
+ deps , src_rsgt -> table .sgl ,
429
374
src_level ,
430
375
i915_ttm_gtt_binds_lmem (bo -> resource ),
431
376
dst_st -> sgl , dst_level ,
@@ -610,18 +555,19 @@ i915_ttm_memcpy_work_arm(struct i915_ttm_memcpy_work *work,
610
555
}
611
556
612
557
static struct dma_fence *
613
- __i915_ttm_move (struct ttm_buffer_object * bo , bool clear ,
558
+ __i915_ttm_move (struct ttm_buffer_object * bo ,
559
+ const struct ttm_operation_ctx * ctx , bool clear ,
614
560
struct ttm_resource * dst_mem , struct ttm_tt * dst_ttm ,
615
561
struct i915_refct_sgt * dst_rsgt , bool allow_accel ,
616
- struct dma_fence * move_dep )
562
+ const struct i915_deps * move_deps )
617
563
{
618
564
struct i915_ttm_memcpy_work * copy_work = NULL ;
619
565
struct i915_ttm_memcpy_arg _arg , * arg = & _arg ;
620
566
struct dma_fence * fence = ERR_PTR (- EINVAL );
621
567
622
568
if (allow_accel ) {
623
569
fence = i915_ttm_accel_move (bo , clear , dst_mem , dst_ttm ,
624
- & dst_rsgt -> table , move_dep );
570
+ & dst_rsgt -> table , move_deps );
625
571
626
572
/*
627
573
* We only need to intercept the error when moving to lmem.
@@ -655,8 +601,8 @@ __i915_ttm_move(struct ttm_buffer_object *bo, bool clear,
655
601
656
602
if (!IS_ERR (fence ))
657
603
goto out ;
658
- } else if (move_dep ) {
659
- int err = dma_fence_wait ( move_dep , true );
604
+ } else if (move_deps ) {
605
+ int err = i915_deps_sync ( move_deps , ctx );
660
606
661
607
if (err )
662
608
return ERR_PTR (err );
@@ -680,29 +626,21 @@ __i915_ttm_move(struct ttm_buffer_object *bo, bool clear,
680
626
return fence ;
681
627
}
682
628
683
- static struct dma_fence * prev_fence (struct ttm_buffer_object * bo ,
684
- struct ttm_operation_ctx * ctx )
629
+ static int
630
+ prev_deps (struct ttm_buffer_object * bo , struct ttm_operation_ctx * ctx ,
631
+ struct i915_deps * deps )
685
632
{
686
- struct i915_deps deps ;
687
633
int ret ;
688
634
689
- /*
690
- * Instead of trying hard with GFP_KERNEL to allocate memory,
691
- * the dependency collection will just sync if it doesn't
692
- * succeed.
693
- */
694
- i915_deps_init (& deps , GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN );
695
- ret = i915_deps_add_dependency (& deps , bo -> moving , ctx );
635
+ ret = i915_deps_add_dependency (deps , bo -> moving , ctx );
696
636
if (!ret )
697
637
/*
698
638
* TODO: Only await excl fence here, and shared fences before
699
639
* signaling the migration fence.
700
640
*/
701
- ret = i915_deps_add_resv (& deps , bo -> base .resv , true, false, ctx );
702
- if (ret )
703
- return ERR_PTR (ret );
641
+ ret = i915_deps_add_resv (deps , bo -> base .resv , true, false, ctx );
704
642
705
- return i915_deps_to_fence ( & deps , ctx ) ;
643
+ return ret ;
706
644
}
707
645
708
646
/**
@@ -756,16 +694,18 @@ int i915_ttm_move(struct ttm_buffer_object *bo, bool evict,
756
694
757
695
clear = !i915_ttm_cpu_maps_iomem (bo -> resource ) && (!ttm || !ttm_tt_is_populated (ttm ));
758
696
if (!(clear && ttm && !(ttm -> page_flags & TTM_TT_FLAG_ZERO_ALLOC ))) {
759
- struct dma_fence * dep = prev_fence ( bo , ctx ) ;
697
+ struct i915_deps deps ;
760
698
761
- if (IS_ERR (dep )) {
699
+ i915_deps_init (& deps , GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN );
700
+ ret = prev_deps (bo , ctx , & deps );
701
+ if (ret ) {
762
702
i915_refct_sgt_put (dst_rsgt );
763
- return PTR_ERR ( dep ) ;
703
+ return ret ;
764
704
}
765
705
766
- migration_fence = __i915_ttm_move (bo , clear , dst_mem , bo -> ttm ,
767
- dst_rsgt , true, dep );
768
- dma_fence_put ( dep );
706
+ migration_fence = __i915_ttm_move (bo , ctx , clear , dst_mem , bo -> ttm ,
707
+ dst_rsgt , true, & deps );
708
+ i915_deps_fini ( & deps );
769
709
}
770
710
771
711
/* We can possibly get an -ERESTARTSYS here */
@@ -826,7 +766,7 @@ int i915_gem_obj_copy_ttm(struct drm_i915_gem_object *dst,
826
766
.interruptible = intr ,
827
767
};
828
768
struct i915_refct_sgt * dst_rsgt ;
829
- struct dma_fence * copy_fence , * dep_fence ;
769
+ struct dma_fence * copy_fence ;
830
770
struct i915_deps deps ;
831
771
int ret , shared_err ;
832
772
@@ -847,15 +787,12 @@ int i915_gem_obj_copy_ttm(struct drm_i915_gem_object *dst,
847
787
if (ret )
848
788
return ret ;
849
789
850
- dep_fence = i915_deps_to_fence (& deps , & ctx );
851
- if (IS_ERR (dep_fence ))
852
- return PTR_ERR (dep_fence );
853
-
854
790
dst_rsgt = i915_ttm_resource_get_st (dst , dst_bo -> resource );
855
- copy_fence = __i915_ttm_move (src_bo , false, dst_bo -> resource ,
791
+ copy_fence = __i915_ttm_move (src_bo , & ctx , false, dst_bo -> resource ,
856
792
dst_bo -> ttm , dst_rsgt , allow_accel ,
857
- dep_fence );
793
+ & deps );
858
794
795
+ i915_deps_fini (& deps );
859
796
i915_refct_sgt_put (dst_rsgt );
860
797
if (IS_ERR_OR_NULL (copy_fence ))
861
798
return PTR_ERR_OR_ZERO (copy_fence );
0 commit comments