@@ -390,24 +390,6 @@ __context_engines_static(const struct i915_gem_context *ctx)
390390 return rcu_dereference_protected (ctx -> engines , true);
391391}
392392
393- static bool __reset_engine (struct intel_engine_cs * engine )
394- {
395- struct intel_gt * gt = engine -> gt ;
396- bool success = false;
397-
398- if (!intel_has_reset_engine (gt ))
399- return false;
400-
401- if (!test_and_set_bit (I915_RESET_ENGINE + engine -> id ,
402- & gt -> reset .flags )) {
403- success = intel_engine_reset (engine , NULL ) == 0 ;
404- clear_and_wake_up_bit (I915_RESET_ENGINE + engine -> id ,
405- & gt -> reset .flags );
406- }
407-
408- return success ;
409- }
410-
411393static void __reset_context (struct i915_gem_context * ctx ,
412394 struct intel_engine_cs * engine )
413395{
@@ -431,12 +413,7 @@ static bool __cancel_engine(struct intel_engine_cs *engine)
431413 * kill the banned context, we fallback to doing a local reset
432414 * instead.
433415 */
434- if (IS_ACTIVE (CONFIG_DRM_I915_PREEMPT_TIMEOUT ) &&
435- !intel_engine_pulse (engine ))
436- return true;
437-
438- /* If we are unable to send a pulse, try resetting this engine. */
439- return __reset_engine (engine );
416+ return intel_engine_pulse (engine ) == 0 ;
440417}
441418
442419static bool
@@ -460,8 +437,8 @@ __active_engine(struct i915_request *rq, struct intel_engine_cs **active)
460437 spin_lock (& locked -> active .lock );
461438 }
462439
463- if (! i915_request_completed (rq )) {
464- if (i915_request_is_active (rq ) && rq -> fence . error != - EIO )
440+ if (i915_request_is_active (rq )) {
441+ if (! i915_request_completed (rq ))
465442 * active = locked ;
466443 ret = true;
467444 }
@@ -479,21 +456,34 @@ static struct intel_engine_cs *active_engine(struct intel_context *ce)
479456 if (!ce -> timeline )
480457 return NULL ;
481458
459+ /*
460+ * rq->link is only SLAB_TYPESAFE_BY_RCU, we need to hold a reference
461+ * to the request to prevent it being transferred to a new timeline
462+ * (and onto a new timeline->requests list).
463+ */
482464 rcu_read_lock ();
483- list_for_each_entry_rcu (rq , & ce -> timeline -> requests , link ) {
484- if (i915_request_is_active (rq ) && i915_request_completed (rq ))
485- continue ;
465+ list_for_each_entry_reverse (rq , & ce -> timeline -> requests , link ) {
466+ bool found ;
467+
468+ /* timeline is already completed upto this point? */
469+ if (!i915_request_get_rcu (rq ))
470+ break ;
486471
487472 /* Check with the backend if the request is inflight */
488- if (__active_engine (rq , & engine ))
473+ found = true;
474+ if (likely (rcu_access_pointer (rq -> timeline ) == ce -> timeline ))
475+ found = __active_engine (rq , & engine );
476+
477+ i915_request_put (rq );
478+ if (found )
489479 break ;
490480 }
491481 rcu_read_unlock ();
492482
493483 return engine ;
494484}
495485
496- static void kill_engines (struct i915_gem_engines * engines )
486+ static void kill_engines (struct i915_gem_engines * engines , bool ban )
497487{
498488 struct i915_gem_engines_iter it ;
499489 struct intel_context * ce ;
@@ -508,7 +498,7 @@ static void kill_engines(struct i915_gem_engines *engines)
508498 for_each_gem_engine (ce , engines , it ) {
509499 struct intel_engine_cs * engine ;
510500
511- if (intel_context_set_banned (ce ))
501+ if (ban && intel_context_set_banned (ce ))
512502 continue ;
513503
514504 /*
@@ -521,7 +511,7 @@ static void kill_engines(struct i915_gem_engines *engines)
521511 engine = active_engine (ce );
522512
523513 /* First attempt to gracefully cancel the context */
524- if (engine && !__cancel_engine (engine ))
514+ if (engine && !__cancel_engine (engine ) && ban )
525515 /*
526516 * If we are unable to send a preemptive pulse to bump
527517 * the context from the GPU, we have to resort to a full
@@ -531,8 +521,10 @@ static void kill_engines(struct i915_gem_engines *engines)
531521 }
532522}
533523
534- static void kill_stale_engines (struct i915_gem_context * ctx )
524+ static void kill_context (struct i915_gem_context * ctx )
535525{
526+ bool ban = (!i915_gem_context_is_persistent (ctx ) ||
527+ !ctx -> i915 -> params .enable_hangcheck );
536528 struct i915_gem_engines * pos , * next ;
537529
538530 spin_lock_irq (& ctx -> stale .lock );
@@ -545,7 +537,7 @@ static void kill_stale_engines(struct i915_gem_context *ctx)
545537
546538 spin_unlock_irq (& ctx -> stale .lock );
547539
548- kill_engines (pos );
540+ kill_engines (pos , ban );
549541
550542 spin_lock_irq (& ctx -> stale .lock );
551543 GEM_BUG_ON (i915_sw_fence_signaled (& pos -> fence ));
@@ -557,11 +549,6 @@ static void kill_stale_engines(struct i915_gem_context *ctx)
557549 spin_unlock_irq (& ctx -> stale .lock );
558550}
559551
560- static void kill_context (struct i915_gem_context * ctx )
561- {
562- kill_stale_engines (ctx );
563- }
564-
565552static void engines_idle_release (struct i915_gem_context * ctx ,
566553 struct i915_gem_engines * engines )
567554{
@@ -596,7 +583,7 @@ static void engines_idle_release(struct i915_gem_context *ctx,
596583
597584kill :
598585 if (list_empty (& engines -> link )) /* raced, already closed */
599- kill_engines (engines );
586+ kill_engines (engines , true );
600587
601588 i915_sw_fence_commit (& engines -> fence );
602589}
@@ -654,9 +641,7 @@ static void context_close(struct i915_gem_context *ctx)
654641 * case we opt to forcibly kill off all remaining requests on
655642 * context close.
656643 */
657- if (!i915_gem_context_is_persistent (ctx ) ||
658- !ctx -> i915 -> params .enable_hangcheck )
659- kill_context (ctx );
644+ kill_context (ctx );
660645
661646 i915_gem_context_put (ctx );
662647}
0 commit comments