@@ -261,14 +261,54 @@ static void free_engines_rcu(struct rcu_head *rcu)
261
261
free_engines (engines );
262
262
}
263
263
264
+ static int __i915_sw_fence_call
265
+ engines_notify (struct i915_sw_fence * fence , enum i915_sw_fence_notify state )
266
+ {
267
+ struct i915_gem_engines * engines =
268
+ container_of (fence , typeof (* engines ), fence );
269
+
270
+ switch (state ) {
271
+ case FENCE_COMPLETE :
272
+ if (!list_empty (& engines -> link )) {
273
+ struct i915_gem_context * ctx = engines -> ctx ;
274
+ unsigned long flags ;
275
+
276
+ spin_lock_irqsave (& ctx -> stale .lock , flags );
277
+ list_del (& engines -> link );
278
+ spin_unlock_irqrestore (& ctx -> stale .lock , flags );
279
+ }
280
+ i915_gem_context_put (engines -> ctx );
281
+ break ;
282
+
283
+ case FENCE_FREE :
284
+ init_rcu_head (& engines -> rcu );
285
+ call_rcu (& engines -> rcu , free_engines_rcu );
286
+ break ;
287
+ }
288
+
289
+ return NOTIFY_DONE ;
290
+ }
291
+
292
+ static struct i915_gem_engines * alloc_engines (unsigned int count )
293
+ {
294
+ struct i915_gem_engines * e ;
295
+
296
+ e = kzalloc (struct_size (e , engines , count ), GFP_KERNEL );
297
+ if (!e )
298
+ return NULL ;
299
+
300
+ i915_sw_fence_init (& e -> fence , engines_notify );
301
+ return e ;
302
+ }
303
+
264
304
static struct i915_gem_engines * default_engines (struct i915_gem_context * ctx )
265
305
{
266
306
const struct intel_gt * gt = & ctx -> i915 -> gt ;
267
307
struct intel_engine_cs * engine ;
268
308
struct i915_gem_engines * e ;
269
309
enum intel_engine_id id ;
270
310
271
- e = kzalloc ( struct_size ( e , engines , I915_NUM_ENGINES ), GFP_KERNEL );
311
+ e = alloc_engines ( I915_NUM_ENGINES );
272
312
if (!e )
273
313
return ERR_PTR (- ENOMEM );
274
314
@@ -519,41 +559,12 @@ static void kill_context(struct i915_gem_context *ctx)
519
559
kill_stale_engines (ctx );
520
560
}
521
561
522
- static int __i915_sw_fence_call
523
- engines_notify (struct i915_sw_fence * fence , enum i915_sw_fence_notify state )
524
- {
525
- struct i915_gem_engines * engines =
526
- container_of (fence , typeof (* engines ), fence );
527
-
528
- switch (state ) {
529
- case FENCE_COMPLETE :
530
- if (!list_empty (& engines -> link )) {
531
- struct i915_gem_context * ctx = engines -> ctx ;
532
- unsigned long flags ;
533
-
534
- spin_lock_irqsave (& ctx -> stale .lock , flags );
535
- list_del (& engines -> link );
536
- spin_unlock_irqrestore (& ctx -> stale .lock , flags );
537
- }
538
- i915_gem_context_put (engines -> ctx );
539
- break ;
540
-
541
- case FENCE_FREE :
542
- init_rcu_head (& engines -> rcu );
543
- call_rcu (& engines -> rcu , free_engines_rcu );
544
- break ;
545
- }
546
-
547
- return NOTIFY_DONE ;
548
- }
549
-
550
562
static void engines_idle_release (struct i915_gem_context * ctx ,
551
563
struct i915_gem_engines * engines )
552
564
{
553
565
struct i915_gem_engines_iter it ;
554
566
struct intel_context * ce ;
555
567
556
- i915_sw_fence_init (& engines -> fence , engines_notify );
557
568
INIT_LIST_HEAD (& engines -> link );
558
569
559
570
engines -> ctx = i915_gem_context_get (ctx );
@@ -1057,6 +1068,30 @@ static void cb_retire(struct i915_active *base)
1057
1068
kfree (cb );
1058
1069
}
1059
1070
1071
+ static inline struct i915_gem_engines *
1072
+ __context_engines_await (const struct i915_gem_context * ctx )
1073
+ {
1074
+ struct i915_gem_engines * engines ;
1075
+
1076
+ rcu_read_lock ();
1077
+ do {
1078
+ engines = rcu_dereference (ctx -> engines );
1079
+ if (unlikely (!engines ))
1080
+ break ;
1081
+
1082
+ if (unlikely (!i915_sw_fence_await (& engines -> fence )))
1083
+ continue ;
1084
+
1085
+ if (likely (engines == rcu_access_pointer (ctx -> engines )))
1086
+ break ;
1087
+
1088
+ i915_sw_fence_complete (& engines -> fence );
1089
+ } while (1 );
1090
+ rcu_read_unlock ();
1091
+
1092
+ return engines ;
1093
+ }
1094
+
1060
1095
I915_SELFTEST_DECLARE (static intel_engine_mask_t context_barrier_inject_fault );
1061
1096
static int context_barrier_task (struct i915_gem_context * ctx ,
1062
1097
intel_engine_mask_t engines ,
@@ -1067,6 +1102,7 @@ static int context_barrier_task(struct i915_gem_context *ctx,
1067
1102
{
1068
1103
struct context_barrier_task * cb ;
1069
1104
struct i915_gem_engines_iter it ;
1105
+ struct i915_gem_engines * e ;
1070
1106
struct intel_context * ce ;
1071
1107
int err = 0 ;
1072
1108
@@ -1083,7 +1119,13 @@ static int context_barrier_task(struct i915_gem_context *ctx,
1083
1119
return err ;
1084
1120
}
1085
1121
1086
- for_each_gem_engine (ce , i915_gem_context_lock_engines (ctx ), it ) {
1122
+ e = __context_engines_await (ctx );
1123
+ if (!e ) {
1124
+ i915_active_release (& cb -> base );
1125
+ return - ENOENT ;
1126
+ }
1127
+
1128
+ for_each_gem_engine (ce , e , it ) {
1087
1129
struct i915_request * rq ;
1088
1130
1089
1131
if (I915_SELFTEST_ONLY (context_barrier_inject_fault &
@@ -1114,7 +1156,7 @@ static int context_barrier_task(struct i915_gem_context *ctx,
1114
1156
if (err )
1115
1157
break ;
1116
1158
}
1117
- i915_gem_context_unlock_engines ( ctx );
1159
+ i915_sw_fence_complete ( & e -> fence );
1118
1160
1119
1161
cb -> task = err ? NULL : task ; /* caller needs to unwind instead */
1120
1162
cb -> data = data ;
@@ -1741,9 +1783,7 @@ set_engines(struct i915_gem_context *ctx,
1741
1783
* first 64 engines defined here.
1742
1784
*/
1743
1785
num_engines = (args -> size - sizeof (* user )) / sizeof (* user -> engines );
1744
-
1745
- set .engines = kmalloc (struct_size (set .engines , engines , num_engines ),
1746
- GFP_KERNEL );
1786
+ set .engines = alloc_engines (num_engines );
1747
1787
if (!set .engines )
1748
1788
return - ENOMEM ;
1749
1789
@@ -1823,7 +1863,7 @@ __copy_engines(struct i915_gem_engines *e)
1823
1863
struct i915_gem_engines * copy ;
1824
1864
unsigned int n ;
1825
1865
1826
- copy = kmalloc ( struct_size ( e , engines , e -> num_engines ), GFP_KERNEL );
1866
+ copy = alloc_engines ( e -> num_engines );
1827
1867
if (!copy )
1828
1868
return ERR_PTR (- ENOMEM );
1829
1869
@@ -2084,7 +2124,7 @@ static int clone_engines(struct i915_gem_context *dst,
2084
2124
bool user_engines ;
2085
2125
unsigned long n ;
2086
2126
2087
- clone = kmalloc ( struct_size ( e , engines , e -> num_engines ), GFP_KERNEL );
2127
+ clone = alloc_engines ( e -> num_engines );
2088
2128
if (!clone )
2089
2129
goto err_unlock ;
2090
2130
0 commit comments