From 160d40ab80d982aff479e3524a0442bb92f78b3d Mon Sep 17 00:00:00 2001
From: Dave Gordon <david.s.gordon@intel.com>
Date: Fri, 17 Apr 2015 22:21:10 +0100
Subject: [PATCH 01/15] drm/i915: Defer default hardware context
initialisation until first open
To fully initialise the default contexts in i915_gem_context_enable(),
we have to execute batchbuffer commands on the GPU engines. But that
might not succeed during early initialisation, so we already treat a
return of EIO as nonfatal in gem_init_hw(), allowing the driver to load
despite not (yet) being able to submit batch commands.
This commit adds a flag to record whether the default contexts have
successfully been initialised; if they haven't, then we retry the
call to i915_gem_context_enable() when the device is first opened,
which should be late enough for all required resources to have become
available and any setup helper code to have run.
Issue: VIZ-4884
Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 1 +
drivers/gpu/drm/i915/i915_gem.c | 4 +++-
drivers/gpu/drm/i915/i915_gem_context.c | 31 ++++++++++++++++++++++++++-----
3 files changed, 30 insertions(+), 6 deletions(-)
@@ -1751,6 +1751,7 @@ struct drm_i915_private {
/* hda/i915 audio component */
bool audio_component_registered;
+ bool contexts_ready;
uint32_t hw_context_size;
struct list_head context_list;
@@ -4889,7 +4889,9 @@ i915_gem_init_hw(struct drm_device *dev)
}
ret = i915_gem_context_enable(dev_priv);
- if (ret && ret != -EIO) {
+ if (ret == 0) {
+ dev_priv->contexts_ready = true;
+ } else if (ret && ret != -EIO) {
DRM_ERROR("Context enable failed %d\n", ret);
i915_gem_cleanup_ringbuffer(dev);
@@ -447,23 +447,44 @@ static int context_idr_cleanup(int id, void *p, void *data)
return 0;
}
+/* Complete any late initialisation here */
+static int i915_gem_context_first_open(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int ret;
+
+ ret = i915_gem_context_enable(dev_priv);
+ if (ret == 0)
+ dev_priv->contexts_ready = true;
+ return ret;
+}
+
int i915_gem_context_open(struct drm_device *dev, struct drm_file *file)
{
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_file_private *file_priv = file->driver_priv;
struct intel_context *ctx;
+ int ret = 0;
idr_init(&file_priv->context_idr);
mutex_lock(&dev->struct_mutex);
- ctx = i915_gem_create_context(dev, file_priv);
+
+ if (!dev_priv->contexts_ready)
+ ret = i915_gem_context_first_open(dev);
+
+ if (ret == 0) {
+ ctx = i915_gem_create_context(dev, file_priv);
+ if (IS_ERR(ctx))
+ ret = PTR_ERR(ctx);
+ }
+
mutex_unlock(&dev->struct_mutex);
- if (IS_ERR(ctx)) {
+ if (ret)
idr_destroy(&file_priv->context_idr);
- return PTR_ERR(ctx);
- }
- return 0;
+ return ret;
}
void i915_gem_context_close(struct drm_device *dev, struct drm_file *file)
--
1.7.9.5