diff mbox series

drm/i915: Keep user GGTT alive for a minimum of 250ms

Message ID 20190523143509.14245-1-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show
Series drm/i915: Keep user GGTT alive for a minimum of 250ms | expand

Commit Message

Chris Wilson May 23, 2019, 2:35 p.m. UTC
Do not allow runtime pm autosuspend to remove userspace GGTT mmaps too
quickly. For example, igt sets the autosuspend delay to 0, and so we
immediately attempt to perform runtime suspend upon releasing the
wakeref. Unfortunately, that involves tearing down GGTT mmaps as they
require an active device.

Override the autosuspend for GGTT mmaps, by keeping the wakeref around
for 250ms after populating the PTE for a fresh mmap.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 drivers/gpu/drm/i915/Kconfig.profile |  4 ++++
 drivers/gpu/drm/i915/i915_drv.h      |  4 ++++
 drivers/gpu/drm/i915/i915_gem.c      | 30 ++++++++++++++++++++++++++++
 3 files changed, 38 insertions(+)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/Kconfig.profile b/drivers/gpu/drm/i915/Kconfig.profile
index 0e5db98da8f3..0f997e221868 100644
--- a/drivers/gpu/drm/i915/Kconfig.profile
+++ b/drivers/gpu/drm/i915/Kconfig.profile
@@ -1,3 +1,7 @@ 
+config DRM_I915_USERFAULT_AUTOSUSPEND
+	int
+	default 250 # milliseconds
+
 config DRM_I915_SPIN_REQUEST
 	int
 	default 5 # microseconds
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 311e19154672..98ba51f255cc 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -874,6 +874,10 @@  struct i915_gem_mm {
 	 */
 	struct list_head userfault_list;
 
+	/* Manual runtime pm autosuspend delay for user GGTT mmaps */
+	intel_wakeref_t userfault_wakeref;
+	struct timer_list userfault_timer;
+
 	/**
 	 * List of objects which are pending destruction.
 	 */
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index d3b7dac527dc..4cb730d52684 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1720,6 +1720,29 @@  compute_partial_view(const struct drm_i915_gem_object *obj,
 	return view;
 }
 
+static void __userfault_timeout(struct timer_list *t)
+{
+	struct drm_i915_private *i915 =
+		from_timer(i915, t, mm.userfault_timer);
+
+	intel_runtime_pm_put(i915, xchg(&i915->mm.userfault_wakeref, 0));
+}
+
+static void userfault_autosuspend(struct drm_i915_private *i915)
+{
+	intel_wakeref_t wakeref;
+
+	if (!CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND)
+		return;
+
+	wakeref = intel_runtime_pm_get(i915);
+	if (cmpxchg(&i915->mm.userfault_wakeref, 0, wakeref))
+		intel_runtime_pm_put(i915, wakeref);
+
+	mod_timer(&i915->mm.userfault_timer,
+		  jiffies + msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND));
+}
+
 /**
  * i915_gem_fault - fault a page into the GTT
  * @vmf: fault info
@@ -1834,6 +1857,7 @@  vm_fault_t i915_gem_fault(struct vm_fault *vmf)
 	assert_rpm_wakelock_held(dev_priv);
 	if (!i915_vma_set_userfault(vma) && !obj->userfault_count++)
 		list_add(&obj->userfault_link, &dev_priv->mm.userfault_list);
+	userfault_autosuspend(dev_priv);
 	GEM_BUG_ON(!obj->userfault_count);
 
 	i915_vma_set_ggtt_write(vma);
@@ -4671,6 +4695,10 @@  void i915_gem_fini(struct drm_i915_private *dev_priv)
 {
 	GEM_BUG_ON(dev_priv->gt.awake);
 
+	if (del_timer_sync(&dev_priv->mm.userfault_timer))
+		__userfault_timeout(&dev_priv->mm.userfault_timer);
+	GEM_BUG_ON(dev_priv->mm.userfault_wakeref);
+
 	i915_gem_suspend_late(dev_priv);
 	intel_disable_gt_powersave(dev_priv);
 
@@ -4748,6 +4776,8 @@  static void i915_gem_init__mm(struct drm_i915_private *i915)
 	INIT_LIST_HEAD(&i915->mm.fence_list);
 	INIT_LIST_HEAD(&i915->mm.userfault_list);
 
+	timer_setup(&i915->mm.userfault_timer, __userfault_timeout, 0);
+
 	INIT_WORK(&i915->mm.free_work, __i915_gem_free_work);
 }