Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> writes: > In order to prevent a race condition where we may end up overaccounting > the active state and leaving the busy-stats believing the GPU is 100% > busy, lock out the tasklet while we reconstruct the busy state. There is > no direct spinlock guard for the execlists->port[], so we need to > utilise tasklet_disable() as a synchronous barrier to prevent the only > writer to execlists->port[] from running at the same time as the enable. > > Fixes: 4900727d35bb ("drm/i915/pmu: Reconstruct active state on starting busy-stats") > Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> > Cc: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> This series applied on drm-tip with j1900. Uptime 2h 35min until system hang. Load was glxgears + video. -Mika > --- > drivers/gpu/drm/i915/intel_engine_cs.c | 20 ++++++++++++-------- > 1 file changed, 12 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c > index d790bdc227ff..b221610f2365 100644 > --- a/drivers/gpu/drm/i915/intel_engine_cs.c > +++ b/drivers/gpu/drm/i915/intel_engine_cs.c > @@ -1943,16 +1943,22 @@ intel_engine_lookup_user(struct drm_i915_private *i915, u8 class, u8 instance) > */ > int intel_enable_engine_stats(struct intel_engine_cs *engine) > { > + struct intel_engine_execlists *execlists = &engine->execlists; > unsigned long flags; > + int err = 0; > > if (!intel_engine_supports_stats(engine)) > return -ENODEV; > > + tasklet_disable(&execlists->tasklet); > spin_lock_irqsave(&engine->stats.lock, flags); > - if (engine->stats.enabled == ~0) > - goto busy; > + > + if (unlikely(engine->stats.enabled == ~0)) { > + err = -EBUSY; > + goto unlock; > + } > + > if (engine->stats.enabled++ == 0) { > - struct intel_engine_execlists *execlists = &engine->execlists; > const struct execlist_port *port = execlists->port; > unsigned int num_ports = execlists_num_ports(execlists); > > @@ -1967,14 +1973,12 @@ int intel_enable_engine_stats(struct intel_engine_cs *engine) > if (engine->stats.active) > engine->stats.start = engine->stats.enabled_at; > } > - spin_unlock_irqrestore(&engine->stats.lock, flags); > > - return 0; > - > -busy: > +unlock: > spin_unlock_irqrestore(&engine->stats.lock, flags); > + tasklet_enable(&execlists->tasklet); > > - return -EBUSY; > + return err; > } > > static ktime_t __intel_engine_get_busy_time(struct intel_engine_cs *engine) > -- > 2.15.1 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/intel-gfx _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx