@@ -1361,7 +1361,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);
@@ -1773,7 +1772,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))
@@ -1362,8 +1362,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)
@@ -1740,7 +1741,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);
@@ -4042,26 +4042,26 @@ 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 || WARN_ON(!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)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- int ret = -ENODEV;
+ int ret;
mutex_lock(&dev->struct_mutex);
@@ -4072,9 +4072,7 @@ int i915_gem_init(struct drm_device *dev)
DRM_DEBUG_DRIVER("allow wake ack timed out\n");
}
- if (intel_enable_ppgtt(dev) && HAS_ALIASING_PPGTT(dev)) {
- struct i915_hw_ppgtt *ppgtt;
-
+ if (intel_enable_ppgtt(dev) && HAS_HW_CONTEXTS(dev)) {
i915_gem_setup_global_gtt(dev, 0, dev_priv->gtt.mappable_end,
dev_priv->gtt.total, false);
i915_gem_context_init(dev);
@@ -4082,30 +4080,19 @@ 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;
}
ggtt_only:
- if (ret) {
- DRM_DEBUG_DRIVER("Aliased PPGTT setup failed %d\n", ret);
+ if (!dev_priv->mm.aliasing_ppgtt) {
+ if (HAS_HW_CONTEXTS(dev))
+ DRM_DEBUG_DRIVER("Context setup failed\n");
i915_gem_setup_global_gtt(dev, 0, dev_priv->gtt.mappable_end,
dev_priv->gtt.total, true);
}
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;
@@ -129,6 +129,7 @@ void i915_gem_context_free(struct kref *ctx_ref)
struct i915_hw_context *ctx = container_of(ctx_ref,
typeof(*ctx), ref);
+ ctx->ppgtt.cleanup(&ctx->ppgtt);
drm_gem_object_unreference(&ctx->obj->base);
kfree(ctx);
}
@@ -167,14 +168,20 @@ 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;
ret = idr_alloc(&file_priv->context_idr, ctx, DEFAULT_CONTEXT_ID + 1, 0,
GFP_KERNEL);
- if (ret < 0)
+ if (ret < 0) {
+ ctx->ppgtt.cleanup(&ctx->ppgtt);
goto err_out;
+ }
ctx->file_priv = file_priv;
ctx->id = ret;
@@ -220,6 +227,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 +301,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)
@@ -375,18 +375,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)
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. NB2: Chris finally gets to disable HW contexts via the PPGTT parameter since they're now tied. Signed-off-by: Ben Widawsky <ben@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 | 47 ++++++++++++--------------------- drivers/gpu/drm/i915/i915_gem_context.c | 11 +++++++- drivers/gpu/drm/i915/i915_gem_gtt.c | 12 --------- 5 files changed, 29 insertions(+), 47 deletions(-)