This is the second half to the previous patch in that now if PPGTT fails to come up, contexts are disabled, and we don't even try to bring up contexts when we don't have PPGTT support. NB: PPGTT cleanup is now done in context unreference. v2: Only cleanup if we set a cleanup vfunc. Don't clean PPGTT up on the failure paths, leave it to unref. Signed-off-by: Ben Widawsky <ben at bwidawsk.net> --- drivers/gpu/drm/i915/i915_dma.c | 2 -- drivers/gpu/drm/i915/i915_drv.h | 4 +-- drivers/gpu/drm/i915/i915_gem.c | 49 ++++++++++++--------------------- drivers/gpu/drm/i915/i915_gem_context.c | 8 ++++++ drivers/gpu/drm/i915/i915_gem_gtt.c | 12 -------- 5 files changed, 28 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index cb08907..b675dc7 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1363,7 +1363,6 @@ cleanup_gem: i915_gem_cleanup_ringbuffer(dev); i915_gem_context_fini(dev); mutex_unlock(&dev->struct_mutex); - i915_gem_cleanup_aliasing_ppgtt(dev); drm_mm_takedown(&dev_priv->mm.gtt_space); cleanup_irq: drm_irq_uninstall(dev); @@ -1748,7 +1747,6 @@ int i915_driver_unload(struct drm_device *dev) i915_gem_cleanup_ringbuffer(dev); i915_gem_context_fini(dev); mutex_unlock(&dev->struct_mutex); - i915_gem_cleanup_aliasing_ppgtt(dev); i915_gem_cleanup_stolen(dev); if (!I915_NEED_GFX_HWS(dev)) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5806d4d..a7f8111 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1454,8 +1454,9 @@ struct drm_i915_file_private { #define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc) #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) -#define HAS_HW_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 6) #define HAS_ALIASING_PPGTT(dev) (INTEL_INFO(dev)->gen >=6 && !IS_VALLEYVIEW(dev)) +#define HAS_HW_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 6 && \ + HAS_ALIASING_PPGTT(dev)) #define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) #define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical) @@ -1843,7 +1844,6 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, /* i915_gem_gtt.c */ bool intel_enable_ppgtt(struct drm_device *dev); int i915_gem_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt); -void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev); void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt, struct drm_i915_gem_object *obj, enum i915_cache_level cache_level); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index a337ce1..c96b422 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4190,20 +4190,20 @@ i915_gem_init_hw(struct drm_device *dev) * goes with our code better). Context switching requires rings (for * the do_switch), but before enabling PPGTT. So don't move this. */ - if (i915_gem_context_enable(dev_priv)) { - i915_gem_context_fini(dev); - dev_priv->hw_contexts_disabled = true; - } + ret = i915_gem_context_enable(dev_priv); + if (ret || !dev_priv->mm.aliasing_ppgtt) + goto disable_ctx_out; - if (dev_priv->mm.aliasing_ppgtt) { - ret = dev_priv->mm.aliasing_ppgtt->enable(dev); - if (ret) { - i915_gem_cleanup_aliasing_ppgtt(dev); - DRM_INFO("PPGTT enable failed. This is not fatal, but unexpected\n"); - } - } + ret = dev_priv->mm.aliasing_ppgtt->enable(dev); + if (ret) + goto disable_ctx_out; return 0; + +disable_ctx_out: + i915_gem_context_fini(dev); + dev_priv->hw_contexts_disabled = true; + return ret; } int i915_gem_init(struct drm_device *dev) @@ -4224,9 +4224,7 @@ int i915_gem_init(struct drm_device *dev) * same, we run through this next section regardless, but don't actually * enable the PPGTT via GFX_MODE. */ - if (HAS_ALIASING_PPGTT(dev)) { - struct i915_hw_ppgtt *ppgtt; - + if (HAS_HW_CONTEXTS(dev)) { i915_gem_setup_global_gtt(dev, 0, dev_priv->gtt.mappable_end, dev_priv->gtt.total, 0); i915_gem_context_init(dev); @@ -4234,31 +4232,20 @@ int i915_gem_init(struct drm_device *dev) drm_mm_takedown(&dev_priv->mm.gtt_space); goto ggtt_only; } - - ppgtt = &dev_priv->ring[RCS].default_context->ppgtt; - - ret = i915_gem_ppgtt_init(dev, ppgtt); - if (ret) { - drm_mm_takedown(&dev_priv->mm.gtt_space); - goto ggtt_only; - } - - dev_priv->mm.aliasing_ppgtt = ppgtt; - } + } else + dev_priv->hw_contexts_disabled = true; ggtt_only: - if (ret) { - if (intel_enable_ppgtt(dev) && HAS_ALIASING_PPGTT(dev)) - DRM_DEBUG_DRIVER("Aliased PPGTT setup fail %d\n", ret); + if (!dev_priv->mm.aliasing_ppgtt) { + if (HAS_HW_CONTEXTS(dev)) + DRM_DEBUG_DRIVER("Context setup failed %d\n", ret); i915_gem_setup_global_gtt(dev, 0, dev_priv->gtt.mappable_end, dev_priv->gtt.total, PAGE_SIZE); } ret = i915_gem_init_hw(dev); - if (ret) { - i915_gem_cleanup_aliasing_ppgtt(dev); + if (ret) i915_gem_context_fini(dev); - } mutex_unlock(&dev->struct_mutex); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 14bdf1d..d92f121 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -129,6 +129,8 @@ void i915_gem_context_free(struct kref *ctx_ref) struct i915_hw_context *ctx = container_of(ctx_ref, typeof(*ctx), ref); + if (ctx->ppgtt.cleanup) + ctx->ppgtt.cleanup(&ctx->ppgtt); drm_gem_object_unreference(&ctx->obj->base); kfree(ctx); } @@ -167,6 +169,10 @@ create_hw_context(struct drm_device *dev, */ ctx->ring = &dev_priv->ring[RCS]; + ret = i915_gem_ppgtt_init(dev, &ctx->ppgtt); + if (ret) + goto err_out; + /* Default context will never have a file_priv */ if (file_priv == NULL) return ctx; @@ -220,6 +226,7 @@ static int create_default_context(struct drm_i915_private *dev_priv) } dev_priv->ring[RCS].default_context = ctx; + dev_priv->mm.aliasing_ppgtt = &ctx->ppgtt; DRM_DEBUG_DRIVER("Default HW context loaded\n"); return 0; @@ -293,6 +300,7 @@ void i915_gem_context_fini(struct drm_device *dev) i915_gem_context_unreference(dctx); dev_priv->ring[RCS].default_context = NULL; dev_priv->ring[RCS].last_context = NULL; + dev_priv->mm.aliasing_ppgtt = NULL; } int i915_gem_context_enable(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index f56e75b..7bbd5c1 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -379,18 +379,6 @@ int i915_gem_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt) return ret; } -void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; - - if (!ppgtt) - return; - - ppgtt->cleanup(ppgtt); - dev_priv->mm.aliasing_ppgtt = NULL; -} - void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt, struct drm_i915_gem_object *obj, enum i915_cache_level cache_level) -- 1.8.3.1