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@xxxxxxxxxxxxxxxxxx> Cc: Mika Kuoppala <mika.kuoppala@xxxxxxxxxxxxxxx> --- 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 --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); } -- 2.20.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx