[Intel-gfx] [PATCH 12/45] drm/i915: Move the engine->destroy() vfunc onto the engine

Chris Wilson chris at chris-wilson.co.uk
Thu Apr 25 11:24:42 UTC 2019


Quoting Tvrtko Ursulin (2019-04-25 12:01:36)
> 
> On 25/04/2019 10:19, Chris Wilson wrote:
> > Make the engine responsible for cleaning itself up!
> 
> Why? (Just a hint to explain in the commit message.)

... so we can remove the vfunc stuck away inside the i915->gt that has
been annoying the reader for the last several years.

> > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> > index 4e30f3720eb7..65cdd0c4accc 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> > @@ -303,6 +303,12 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
> >       engine->class = info->class;
> >       engine->instance = info->instance;
> >   
> > +     /*
> > +      * To be overridden by the backend on setup, however to facilitate
> > +      * cleanup on error during setup we always provide the destroy vfunc.
> > +      */
> > +     engine->destroy = (typeof(engine->destroy))kfree;
> 
> Scheme overall is nice but has one fragile point in it.
> 
> I think we want a wrapper and then add some WARN_ON type safety if the 
> engine has state allocated and the destroy vfunc accidentally still 
> points to this one.
> 
> I suspect easiest would be to set an engine flag once it has been 
> initialized.

Hmm, still fragile since you rely on the user? And if you don't rely on
the user, we just put a GEM_BUG_ON(engine->destroy == kfree) at the
point where we expect the backend to take control, i.e. after a
successful call to setup() in intel_engines_setup.

@@ -617,6 +617,9 @@ int intel_engines_setup(struct drm_i915_private *i915)
                if (err)
                        goto cleanup;

+               /* We expect the backend to take control over its state */
+               GEM_BUG_ON(engine->destroy == (typeof(engine->destroy))kfree);
+
                GEM_BUG_ON(!engine->cops);
> 
> > +
> >       engine->uabi_class = intel_engine_classes[info->class].uabi_class;
> >   
> >       engine->context_size = __intel_engine_context_size(dev_priv,
> > @@ -327,18 +333,31 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
> >       return 0;
> >   }
> >   
> > +/**
> > + * intel_engines_cleanup() - free the resources allocated for Command Streamers
> > + * @dev_priv: i915 device private
> > + */
> > +void intel_engines_cleanup(struct drm_i915_private *i915)
> > +{
> > +     struct intel_engine_cs *engine;
> > +     enum intel_engine_id id;
> > +
> > +     for_each_engine(engine, i915, id) {
> > +             engine->destroy(engine);
> > +             i915->engine[id] = NULL;
> > +     }
> > +}
> > +
> >   /**
> >    * intel_engines_init_mmio() - allocate and prepare the Engine Command Streamers
> >    * @dev_priv: i915 device private
> >    *
> >    * Return: non-zero if the initialization failed.
> >    */
> > -int intel_engines_init_mmio(struct drm_i915_private *dev_priv)
> > +int intel_engines_init_mmio(struct drm_i915_private *i915)
> >   {
> > -     struct intel_device_info *device_info = mkwrite_device_info(dev_priv);
> > -     const unsigned int engine_mask = INTEL_INFO(dev_priv)->engine_mask;
> > -     struct intel_engine_cs *engine;
> > -     enum intel_engine_id id;
> > +     struct intel_device_info *device_info = mkwrite_device_info(i915);
> > +     const unsigned int engine_mask = INTEL_INFO(i915)->engine_mask;
> >       unsigned int mask = 0;
> >       unsigned int i;
> >       int err;
> > @@ -351,10 +370,10 @@ int intel_engines_init_mmio(struct drm_i915_private *dev_priv)
> >               return -ENODEV;
> >   
> >       for (i = 0; i < ARRAY_SIZE(intel_engines); i++) {
> > -             if (!HAS_ENGINE(dev_priv, i))
> > +             if (!HAS_ENGINE(i915, i))
> >                       continue;
> >   
> > -             err = intel_engine_setup(dev_priv, i);
> > +             err = intel_engine_setup(i915, i);
> 
> While nosing around I noticed there is mmio access in setup. :(

Yeah, we can take another step or two to split up the phases between sw
setup and HW setup.
-Chris


More information about the Intel-gfx mailing list