| From 4370ef17e5269a02647a350abbdcb6ae171a41b7 Mon Sep 17 00:00:00 2001 |
| From: Daniel Vetter <daniel.vetter@ffwll.ch> |
| Date: Tue, 9 Jul 2013 16:51:37 +0200 |
| Subject: drm/i915: don't frob mm.suspended when not using ums |
| |
| In kernel modeset driver mode we're in full control of the chip, |
| always. So there's no need at all to set mm.suspended in |
| i915_gem_idle. Hence move that out into the leavevt ioctl. Since |
| i915_gem_idle doesn't suspend gem any more we can also drop the |
| re-enabling for KMS in the thaw function. |
| |
| Also clean up the handling of mm.suspend at driver load by coalescing |
| all the assignments. |
| |
| Stumbled over while reading through our resume code for unrelated |
| reasons. |
| |
| v2: Shovel mm.suspended into the (newly created) ums dungeon as |
| suggested by Chris Wilson. The plan is that once we've completely |
| stopped relying on the register save/restore code we could shovel even |
| that in there. |
| |
| v3: Improve the locking for the entervt/leavevt ioctls a bit by moving |
| the dev->struct_mutex locking outside of i915_gem_idle. Also don't |
| clear dev_priv->ums.mm_suspended for the kms case, we allocate it with |
| kzalloc. Both suggested by Chris Wilson. |
| |
| Cc: Chris Wilson <chris@chris-wilson.co.uk> |
| Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> (v2) |
| Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> |
| (cherry picked from commit db1b76ca6a79c774074ae87bee7afc0825a478f5) |
| Signed-off-by: James Ausmus <james.ausmus@intel.com> |
| |
| Conflicts: |
| drivers/gpu/drm/i915/i915_gem.c |
| (used airlied's rerere from |
| e13af9a8340685cfe25d0c9f708da7121e0f51dd) |
| Signed-off-by: Darren Hart <dvhart@linux.intel.com> |
| --- |
| drivers/gpu/drm/i915/i915_dma.c | 13 ++------- |
| drivers/gpu/drm/i915/i915_drv.c | 11 +++++-- |
| drivers/gpu/drm/i915/i915_drv.h | 24 ++++++++++------- |
| drivers/gpu/drm/i915/i915_gem.c | 40 +++++++++++++++++------------ |
| drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 - |
| 5 files changed, 50 insertions(+), 40 deletions(-) |
| |
| --- a/drivers/gpu/drm/i915/i915_dma.c |
| +++ b/drivers/gpu/drm/i915/i915_dma.c |
| @@ -1331,10 +1331,8 @@ static int i915_load_modeset_init(struct |
| /* Always safe in the mode setting case. */ |
| /* FIXME: do pre/post-mode set stuff in core KMS code */ |
| dev->vblank_disable_allowed = 1; |
| - if (INTEL_INFO(dev)->num_pipes == 0) { |
| - dev_priv->mm.suspended = 0; |
| + if (INTEL_INFO(dev)->num_pipes == 0) |
| return 0; |
| - } |
| |
| ret = intel_fbdev_init(dev); |
| if (ret) |
| @@ -1360,9 +1358,6 @@ static int i915_load_modeset_init(struct |
| |
| drm_kms_helper_poll_init(dev); |
| |
| - /* We're off and running w/KMS */ |
| - dev_priv->mm.suspended = 0; |
| - |
| return 0; |
| |
| cleanup_gem: |
| @@ -1639,9 +1634,6 @@ int i915_driver_load(struct drm_device * |
| goto out_gem_unload; |
| } |
| |
| - /* Start out suspended */ |
| - dev_priv->mm.suspended = 1; |
| - |
| if (HAS_POWER_WELL(dev)) |
| i915_init_power_well(dev); |
| |
| @@ -1651,6 +1643,9 @@ int i915_driver_load(struct drm_device * |
| DRM_ERROR("failed to init modeset\n"); |
| goto out_gem_unload; |
| } |
| + } else { |
| + /* Start out suspended in ums mode. */ |
| + dev_priv->ums.mm_suspended = 1; |
| } |
| |
| i915_setup_sysfs(dev); |
| --- a/drivers/gpu/drm/i915/i915_drv.c |
| +++ b/drivers/gpu/drm/i915/i915_drv.c |
| @@ -556,7 +556,11 @@ static int i915_drm_freeze(struct drm_de |
| |
| /* If KMS is active, we do the leavevt stuff here */ |
| if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
| - int error = i915_gem_idle(dev); |
| + int error; |
| + |
| + mutex_lock(&dev->struct_mutex); |
| + error = i915_gem_idle(dev); |
| + mutex_unlock(&dev->struct_mutex); |
| if (error) { |
| dev_err(&dev->pdev->dev, |
| "GEM idle failed, resume might fail\n"); |
| @@ -661,7 +665,6 @@ static int __i915_drm_thaw(struct drm_de |
| intel_init_pch_refclk(dev); |
| |
| mutex_lock(&dev->struct_mutex); |
| - dev_priv->mm.suspended = 0; |
| |
| error = i915_gem_init_hw(dev); |
| mutex_unlock(&dev->struct_mutex); |
| @@ -961,11 +964,11 @@ int i915_reset(struct drm_device *dev) |
| * switched away). |
| */ |
| if (drm_core_check_feature(dev, DRIVER_MODESET) || |
| - !dev_priv->mm.suspended) { |
| + !dev_priv->ums.mm_suspended) { |
| struct intel_ring_buffer *ring; |
| int i; |
| |
| - dev_priv->mm.suspended = 0; |
| + dev_priv->ums.mm_suspended = 0; |
| |
| i915_gem_init_swizzling(dev); |
| |
| --- a/drivers/gpu/drm/i915/i915_drv.h |
| +++ b/drivers/gpu/drm/i915/i915_drv.h |
| @@ -815,6 +815,18 @@ struct i915_dri1_state { |
| uint32_t counter; |
| }; |
| |
| +struct i915_ums_state { |
| + /** |
| + * Flag if the X Server, and thus DRM, is not currently in |
| + * control of the device. |
| + * |
| + * This is set between LeaveVT and EnterVT. It needs to be |
| + * replaced with a semaphore. It also needs to be |
| + * transitioned away from for kernel modesetting. |
| + */ |
| + int mm_suspended; |
| +}; |
| + |
| struct intel_l3_parity { |
| u32 *remap_info; |
| struct work_struct error_work; |
| @@ -885,16 +897,6 @@ struct i915_gem_mm { |
| */ |
| bool interruptible; |
| |
| - /** |
| - * Flag if the X Server, and thus DRM, is not currently in |
| - * control of the device. |
| - * |
| - * This is set between LeaveVT and EnterVT. It needs to be |
| - * replaced with a semaphore. It also needs to be |
| - * transitioned away from for kernel modesetting. |
| - */ |
| - int suspended; |
| - |
| /** Bit 6 swizzling required for X tiling */ |
| uint32_t bit_6_swizzle_x; |
| /** Bit 6 swizzling required for Y tiling */ |
| @@ -1188,6 +1190,8 @@ typedef struct drm_i915_private { |
| /* Old dri1 support infrastructure, beware the dragons ya fools entering |
| * here! */ |
| struct i915_dri1_state dri1; |
| + /* Old ums support infrastructure, same warning applies. */ |
| + struct i915_ums_state ums; |
| } drm_i915_private_t; |
| |
| /* Iterate over initialised rings */ |
| --- a/drivers/gpu/drm/i915/i915_gem.c |
| +++ b/drivers/gpu/drm/i915/i915_gem.c |
| @@ -2086,7 +2086,7 @@ int __i915_add_request(struct intel_ring |
| trace_i915_gem_request_add(ring, request->seqno); |
| ring->outstanding_lazy_request = 0; |
| |
| - if (!dev_priv->mm.suspended) { |
| + if (!dev_priv->ums.mm_suspended) { |
| if (i915_enable_hangcheck) { |
| mod_timer(&dev_priv->gpu_error.hangcheck_timer, |
| round_jiffies_up(jiffies + DRM_I915_HANGCHECK_JIFFIES)); |
| @@ -2401,7 +2401,7 @@ i915_gem_retire_work_handler(struct work |
| idle &= list_empty(&ring->request_list); |
| } |
| |
| - if (!dev_priv->mm.suspended && !idle) |
| + if (!dev_priv->ums.mm_suspended && !idle) |
| queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, |
| round_jiffies_up_relative(HZ)); |
| if (idle) |
| @@ -3978,9 +3978,7 @@ i915_gem_idle(struct drm_device *dev) |
| drm_i915_private_t *dev_priv = dev->dev_private; |
| int ret; |
| |
| - mutex_lock(&dev->struct_mutex); |
| - |
| - if (dev_priv->mm.suspended) { |
| + if (dev_priv->ums.mm_suspended) { |
| mutex_unlock(&dev->struct_mutex); |
| return 0; |
| } |
| @@ -3996,18 +3994,11 @@ i915_gem_idle(struct drm_device *dev) |
| if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
| i915_gem_evict_everything(dev); |
| |
| - /* Hack! Don't let anybody do execbuf while we don't control the chip. |
| - * We need to replace this with a semaphore, or something. |
| - * And not confound mm.suspended! |
| - */ |
| - dev_priv->mm.suspended = 1; |
| del_timer_sync(&dev_priv->gpu_error.hangcheck_timer); |
| |
| i915_kernel_lost_context(dev); |
| i915_gem_cleanup_ringbuffer(dev); |
| |
| - mutex_unlock(&dev->struct_mutex); |
| - |
| /* Cancel the retire work handler, which should be idle now. */ |
| cancel_delayed_work_sync(&dev_priv->mm.retire_work); |
| |
| @@ -4217,7 +4208,7 @@ int |
| i915_gem_entervt_ioctl(struct drm_device *dev, void *data, |
| struct drm_file *file_priv) |
| { |
| - drm_i915_private_t *dev_priv = dev->dev_private; |
| + struct drm_i915_private *dev_priv = dev->dev_private; |
| int ret; |
| |
| if (drm_core_check_feature(dev, DRIVER_MODESET)) |
| @@ -4229,7 +4220,7 @@ i915_gem_entervt_ioctl(struct drm_device |
| } |
| |
| mutex_lock(&dev->struct_mutex); |
| - dev_priv->mm.suspended = 0; |
| + dev_priv->ums.mm_suspended = 0; |
| |
| ret = i915_gem_init_hw(dev); |
| if (ret != 0) { |
| @@ -4249,7 +4240,7 @@ i915_gem_entervt_ioctl(struct drm_device |
| cleanup_ringbuffer: |
| mutex_lock(&dev->struct_mutex); |
| i915_gem_cleanup_ringbuffer(dev); |
| - dev_priv->mm.suspended = 1; |
| + dev_priv->ums.mm_suspended = 1; |
| mutex_unlock(&dev->struct_mutex); |
| |
| return ret; |
| @@ -4259,11 +4250,26 @@ int |
| i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, |
| struct drm_file *file_priv) |
| { |
| + struct drm_i915_private *dev_priv = dev->dev_private; |
| + int ret; |
| + |
| if (drm_core_check_feature(dev, DRIVER_MODESET)) |
| return 0; |
| |
| drm_irq_uninstall(dev); |
| - return i915_gem_idle(dev); |
| + |
| + mutex_lock(&dev->struct_mutex); |
| + ret = i915_gem_idle(dev); |
| + |
| + /* Hack! Don't let anybody do execbuf while we don't control the chip. |
| + * We need to replace this with a semaphore, or something. |
| + * And not confound ums.mm_suspended! |
| + */ |
| + if (ret != 0) |
| + dev_priv->ums.mm_suspended = 1; |
| + mutex_unlock(&dev->struct_mutex); |
| + |
| + return ret; |
| } |
| |
| void |
| @@ -4274,9 +4280,11 @@ i915_gem_lastclose(struct drm_device *de |
| if (drm_core_check_feature(dev, DRIVER_MODESET)) |
| return; |
| |
| + mutex_lock(&dev->struct_mutex); |
| ret = i915_gem_idle(dev); |
| if (ret) |
| DRM_ERROR("failed to idle hardware: %d\n", ret); |
| + mutex_unlock(&dev->struct_mutex); |
| } |
| |
| static void |
| --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c |
| +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c |
| @@ -973,7 +973,7 @@ i915_gem_do_execbuffer(struct drm_device |
| if (ret) |
| goto pre_mutex_err; |
| |
| - if (dev_priv->mm.suspended) { |
| + if (dev_priv->ums.mm_suspended) { |
| mutex_unlock(&dev->struct_mutex); |
| ret = -EBUSY; |
| goto pre_mutex_err; |