diff mbox

[2/2] drm/i915: Defer late hardware initialisation until first open

Message ID 1435676471-30925-2-git-send-email-david.s.gordon@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Dave Gordon June 30, 2015, 3:01 p.m. UTC
We can do less work during driver load by deferring some of it until
the first time the device is opened; in particular, the function
i915_gem_init_hw_late() introduced by the previous patch. This should
allow the system to get out of the early single-threaded phase of
system initialisation and into full multi-user mode somewhat quicker.

In addition, we expect that by the time of the first open, not only
the driver's software structures but also system-specific items such
as filesystem mounting have been fully initialised, meaning that the
late initialisation code can run in a much more complete environment
than the driver_load stage presents. This can be important for
embedded programmable devices that need firmware loaded from a file
before they can be used.

Signed-off-by: Dave Gordon <david.s.gordon@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 |   32 ++++++++++++++++++++++++++-----
 3 files changed, 31 insertions(+), 6 deletions(-)

Comments

Chris Wilson June 30, 2015, 3:08 p.m. UTC | #1
On Tue, Jun 30, 2015 at 04:01:11PM +0100, Dave Gordon wrote:
> We can do less work during driver load by deferring some of it until
> the first time the device is opened; in particular, the function
> i915_gem_init_hw_late() introduced by the previous patch. This should
> allow the system to get out of the early single-threaded phase of
> system initialisation and into full multi-user mode somewhat quicker.
> 
> In addition, we expect that by the time of the first open, not only
> the driver's software structures but also system-specific items such
> as filesystem mounting have been fully initialised, meaning that the
> late initialisation code can run in a much more complete environment
> than the driver_load stage presents. This can be important for
> embedded programmable devices that need firmware loaded from a file
> before they can be used.

No. It delays establising the power contexts. Something that in the past
we have been told must be done asap. You can move it to an async worker,
that would be achieve the goals stated here, and not be dependent on a
cooperating userspace.
-Chris
Shuang He July 2, 2015, 12:20 p.m. UTC | #2
Tested-By: Intel Graphics QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com)
Task id: 6687
-------------------------------------Summary-------------------------------------
Platform          Delta          drm-intel-nightly          Series Applied
ILK                                  302/302              302/302
SNB                                  312/316              312/316
IVB                                  343/343              343/343
BYT                 -1              287/287              286/287
HSW                                  380/380              380/380
-------------------------------------Detailed-------------------------------------
Platform  Test                                drm-intel-nightly          Series Applied
*BYT  igt@gem_partial_pwrite_pread@reads-display      PASS(1)      FAIL(1)
Note: You need to pay more attention to line start with '*'
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index bc7c510..ba63804 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1845,6 +1845,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;
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 1887e60..0cb962f 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -5073,7 +5073,9 @@  i915_gem_init_hw(struct drm_device *dev)
 			goto out;
 	}
 
-	ret = i915_gem_init_hw_late(dev);
+	/* Don't do late init on the first time through here */
+	if (dev_priv->contexts_ready)
+		ret = i915_gem_init_hw_late(dev);
 
 out:
 	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index a7e58a8..917c867 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -438,23 +438,45 @@  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_init_hw_late(dev);
+	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)